๐ Project Overview โ What We Are Building
A grocery shop billing system. The shop has an inventory of products stored in a struct array โ each product has a name, price, category, and stock. A customer adds items to a cart (another struct array). The system generates a formatted bill with subtotal, GST tax, and loyalty discount. Every major C concept โ struct, pointer, array, function, function pointer โ appears in a real, working role.
Two struct arrays โ inventory and cart โ communicate through pointer functions. Stock decreases when items are added. The bill function is pluggable via function pointer.
| Struct | Fields | Role | How accessed |
|---|---|---|---|
| Product | name, category, price, stock | Shop inventory โ 8 products | const Product* for display, Product* to update stock |
| CartItem | name, price, qty, subtotal | Customer's basket | CartItem* to add items, const CartItem* for bill |
- 1Product struct โ
char name[30],char category[15],float price,int stock. Represents one shelf item. - 2CartItem struct โ
char name[30],float unitPrice,int qty,float subtotal. Computed at add-time:subtotal = unitPrice * qty. - 3Initialise inventory โ array of 8 Products with prices and stock counts. This is the shop's permanent record.
- 4Define constants โ
MAX_PRODUCTS,MAX_CART,GST_RATE,DISCOUNT_THRESHOLDโ keeps magic numbers out of functions.
#include <stdio.h> #include <string.h> #define MAX_PRODUCTS 8 #define MAX_CART 10 #define GST_RATE 0.05f /* 5% GST */ #define DISC_THRESHOLD 500.0f /* 10% off if bill > Rs 500 */ /* โโ PRODUCT โ one item on the shop shelf โโ */ typedef struct { char name[30]; /* "Basmati Rice 1kg" */ char category[15]; /* "Grains" */ float price; /* price per unit in Rs */ int stock; /* units available */ } Product; /* โโ CART ITEM โ what customer picks โโ */ typedef struct { char name[30]; float unitPrice; int qty; float subtotal; /* unitPrice * qty */ } CartItem; /* โโ SHOP INVENTORY โ 8 products โโ */ Product initShop() { /* Returned for illustration โ in main we use array directly */ Product p = {"Basmati Rice 1kg", "Grains", 75.0f, 50}; return p; } int main() { /* Full inventory โ array of 8 Product structs */ Product shop[MAX_PRODUCTS] = { {"Basmati Rice 1kg", "Grains", 75.0f, 50}, {"Toor Dal 500g", "Pulses", 65.0f, 40}, {"Sunflower Oil 1L", "Oils", 140.0f, 30}, {"Whole Wheat Atta", "Grains", 55.0f, 60}, {"Amul Butter 100g", "Dairy", 52.0f, 25}, {"Full Cream Milk 1L","Dairy", 68.0f, 35}, {"Turmeric Powder", "Spices", 30.0f, 80}, {"Sugar 1kg", "Essentials",42.0f, 70} }; printf("sizeof(Product) = %zu bytes\n", sizeof(Product)); printf("sizeof(CartItem) = %zu bytes\n", sizeof(CartItem)); printf("Shop loaded with %d products.\n", MAX_PRODUCTS); printf("First product: %s @ Rs %.2f (stock: %d)\n", shop[0].name, shop[0].price, shop[0].stock); return 0; }
sizeof(Product) = 52 bytes sizeof(CartItem) = 48 bytes Shop loaded with 8 products. First product: Basmati Rice 1kg @ Rs 75.00 (stock: 50)
Product is permanent โ it lives for the entire program and tracks real inventory. CartItem is per-transaction โ it only holds what the customer picked. Keeping them separate makes the code clean: display functions take const Product*, billing functions take const CartItem*.const Product *shop because they only read. displayAll prints every product in a formatted table with a numbered index. displayByCategory walks the same array with a pointer, using strcmp to match the category and skipping non-matches. Passing const pointer means even if someone accidentally tries to write shop[i].stock = 0 inside these functions, the compiler refuses.
- 1
const Product *shopโ function promises read-only. Compiler enforces. Safe to call with any product array. - 2Formatted table โ
printf("%-3d %-22s %-12s %7.2f %6d\n", ...)โ left-align strings, right-align numbers. Width specifiers keep columns neat. - 3Low stock alert โ inside the walk, flag products where
stock < 10with a"LOW"marker. One pass, two jobs. - 4Category filter โ
if(strcmp(shop[i].category, cat) != 0) continue;โ skip non-matching rows cleanly.
#include <stdio.h> #include <string.h> typedef struct{char name[30];char category[15];float price;int stock;}Product; /* Display all products โ const: read-only */ void displayAll(const Product *shop, int n) { printf("\n%-3s %-22s %-12s %7s %6s\n", "No","Product","Category","Price","Stock"); printf("%-3s %-22s %-12s %7s %6s\n", "---","----------------------","------------","-------","------"); for (int i = 0; i < n; i++) { printf("%-3d %-22s %-12s %7.2f %6d", i+1, shop[i].name, shop[i].category, shop[i].price, shop[i].stock); if (shop[i].stock < 10) printf(" *** LOW"); printf("\n"); } } /* Display by category โ skip non-matching */ void displayByCategory(const Product *shop, int n, const char *cat) { printf("\n--- Category: %s ---\n", cat); int found = 0; for (int i = 0; i < n; i++) { if (strcmp(shop[i].category, cat) != 0) continue; printf(" %-22s Rs %7.2f (stock: %d)\n", shop[i].name, shop[i].price, shop[i].stock); found++; } if (!found) printf(" No products in this category.\n"); } int main() { Product shop[] = { {"Basmati Rice 1kg", "Grains", 75.0f, 50}, {"Toor Dal 500g", "Pulses", 65.0f, 40}, {"Sunflower Oil 1L", "Oils", 140.0f, 7}, {"Whole Wheat Atta", "Grains", 55.0f, 60}, {"Amul Butter 100g", "Dairy", 52.0f, 25}, {"Full Cream Milk 1L","Dairy", 68.0f, 8}, {"Turmeric Powder", "Spices", 30.0f, 80}, {"Sugar 1kg", "Essentials",42.0f,70} }; displayAll(shop, 8); displayByCategory(shop, 8, "Dairy"); return 0; }
No Product Category Price Stock --- ---------------------- ------------ ------- ------ 1 Basmati Rice 1kg Grains 75.00 50 2 Toor Dal 500g Pulses 65.00 40 3 Sunflower Oil 1L Oils 140.00 7 *** LOW 4 Whole Wheat Atta Grains 55.00 60 5 Amul Butter 100g Dairy 52.00 25 6 Full Cream Milk 1L Dairy 68.00 8 *** LOW 7 Turmeric Powder Spices 30.00 80 8 Sugar 1kg Essentials 42.00 70 --- Category: Dairy --- Amul Butter 100g Rs 52.00 (stock: 25) Full Cream Milk 1L Rs 68.00 (stock: 8)
if(stock < 10) adds a warning to the same row without a second loop. This is the pointer walk advantage โ you process each element once and do everything you need in a single pass.Product *shop (not const โ because we need to reduce stock) and CartItem *cart (to fill a new cart slot). After validating the product exists and has enough stock, we: copy the product name and price into a new CartItem, set the quantity, compute the subtotal, then decrement the stock on the original product through the pointer. Both the inventory and the cart are updated in one function call.
- 1Find product by index โ user picks a number (1โ8). Validate:
idx >= 0 && idx < n. - 2Check stock โ
if(shop[idx].stock < qty)print "out of stock" and return 0 (failure signal). - 3Fill CartItem โ
strncpy(cart[*cartCount].name, shop[idx].name, 29). Copy price and qty. Compute subtotal. - 4Update stock โ
shop[idx].stock -= qtyโ modifies the real inventory through the non-const pointer. Increment*cartCount.
#include <stdio.h> #include <string.h> typedef struct{char name[30];char category[15];float price;int stock;}Product; typedef struct{char name[30];float unitPrice;int qty;float subtotal;}CartItem; /* Returns 1 on success, 0 on failure Modifies shop[idx].stock AND fills cart[*cartCount] */ int addToCart(Product *shop, int shopSize, CartItem *cart, int *cartCount, int productIdx, int qty) { /* Validate index */ if (productIdx < 0 || productIdx >= shopSize) { printf(" Invalid product number.\n"); return 0; } Product *p = &shop[productIdx]; /* pointer to chosen product */ /* Validate stock */ if (p->stock < qty) { printf(" Sorry! Only %d units of %s in stock.\n", p->stock, p->name); return 0; } /* Validate cart space */ if (*cartCount >= 10) { printf(" Cart is full (max 10 items).\n"); return 0; } /* Fill cart slot via pointer */ CartItem *slot = &cart[*cartCount]; strncpy(slot->name, p->name, 29); slot->unitPrice = p->price; slot->qty = qty; slot->subtotal = p->price * qty; /* Deduct stock from real inventory โ non-const pointer */ p->stock -= qty; (*cartCount)++; /* advance cart counter via pointer */ printf(" Added: %s x%d = Rs %.2f\n", slot->name, qty, slot->subtotal); return 1; } void showCart(const CartItem *cart, int n) { printf("\n--- Cart (%d items) ---\n", n); for(int i=0;i<n;i++) printf(" %-22s x%-3d Rs %.2f\n", cart[i].name, cart[i].qty, cart[i].subtotal); } int main() { Product shop[] = { {"Basmati Rice 1kg", "Grains", 75.0f, 50}, {"Toor Dal 500g", "Pulses", 65.0f, 40}, {"Sunflower Oil 1L","Oils", 140.0f, 3}, {"Amul Butter 100g","Dairy", 52.0f, 25} }; CartItem cart[10]; int cartCount = 0; printf("=== Customer Shopping ===\n"); addToCart(shop, 4, cart, &cartCount, 0, 2); /* Rice x2 */ addToCart(shop, 4, cart, &cartCount, 1, 1); /* Dal x1 */ addToCart(shop, 4, cart, &cartCount, 2, 5); /* Oil x5 โ fail */ addToCart(shop, 4, cart, &cartCount, 2, 2); /* Oil x2 */ showCart(cart, cartCount); printf("\nStock after shopping:\n"); printf(" Rice stock now: %d\n", shop[0].stock); printf(" Oil stock now: %d\n", shop[2].stock); return 0; }
=== Customer Shopping === Added: Basmati Rice 1kg x2 = Rs 150.00 Added: Toor Dal 500g x1 = Rs 65.00 Sorry! Only 3 units of Sunflower Oil 1L in stock. Added: Sunflower Oil 1L x2 = Rs 280.00 --- Cart (3 items) --- Basmati Rice 1kg x2 Rs 150.00 Toor Dal 500g x1 Rs 65.00 Sunflower Oil 1L x2 Rs 280.00 Stock after shopping: Rice stock now: 48 Oil stock now: 1
int *cartCount not int cartCount? The function must increment the caller's counter. Passing by value would give the function a copy โ the caller would never see the count increase. Passing &cartCount and incrementing via (*cartCount)++ updates the real counter in main.const CartItem* pointer โ it only reads. It computes the subtotal by summing all item.subtotal values, applies 5% GST, then applies a 10% loyalty discount if the subtotal exceeds Rs 500. A function pointer selects between a detailed bill format and a compact receipt โ same calculation, pluggable output style.
- 1Subtotal โ pointer walk:
for(i=0; i<n; i++) total += cart[i].subtotal. Returnsfloat. - 2GST โ
float gst = subtotal * GST_RATE. Added to total. Printed as separate line on bill. - 3Discount โ
if(subtotal > DISC_THRESHOLD) discount = subtotal * 0.10f. Applied before tax. Prints "Loyalty Discount" line. - 4Function pointer โ
void (*printFn)(const CartItem*, int, float, float, float)โ caller passesprintDetailedorprintCompact.
#include <stdio.h> #include <time.h> typedef struct{char name[30];float unitPrice;int qty;float subtotal;}CartItem; #define GST_RATE 0.05f #define DISC_THRESHOLD 500.0f #define DISC_RATE 0.10f /* Compute grand total โ returns via output pointers */ float calcTotal(const CartItem *cart, int n, float *gstOut, float *discOut) { float subtotal = 0; for (int i = 0; i < n; i++) subtotal += cart[i].subtotal; *discOut = (subtotal > DISC_THRESHOLD) ? subtotal * DISC_RATE : 0.0f; *gstOut = (subtotal - *discOut) * GST_RATE; return subtotal - *discOut + *gstOut; } /* Detailed bill โ itemised */ void printDetailed(const CartItem *cart, int n, float grand, float gst, float disc) { time_t now = time(NULL); printf("\n================================================\n"); printf(" ANANTA GROCERY STORE\n"); printf(" %s", ctime(&now)); printf("================================================\n"); printf("%-22s %5s %10s\n","Item","Qty","Amount"); printf("------------------------------------------------\n"); float subtotal = 0; for (int i = 0; i < n; i++) { printf("%-22s %5d %10.2f\n", cart[i].name, cart[i].qty, cart[i].subtotal); subtotal += cart[i].subtotal; } printf("------------------------------------------------\n"); printf("%-27s %10.2f\n", "Subtotal", subtotal); if (disc > 0) printf("%-27s %10.2f\n", "Loyalty Discount (10%)", -disc); printf("%-27s %10.2f\n", "GST (5%)", gst); printf("================================================\n"); printf("%-27s %10.2f\n", "GRAND TOTAL", grand); printf("================================================\n"); printf(" Thank you for shopping with us!\n"); printf("================================================\n"); } /* Compact receipt */ void printCompact(const CartItem *cart, int n, float grand, float gst, float disc) { printf("\n[RECEIPT] Items:%d GST:%.2f Disc:%.2f TOTAL: Rs %.2f\n", n, gst, disc, grand); } int main() { CartItem cart[] = { {"Basmati Rice 1kg", 75.0f, 3, 225.0f}, {"Toor Dal 500g", 65.0f, 2, 130.0f}, {"Sunflower Oil 1L",140.0f, 2, 280.0f}, {"Sugar 1kg", 42.0f, 1, 42.0f} }; int n = 4; float gst, disc; float grand = calcTotal(cart, n, &gst, &disc); /* Function pointer โ swap bill style */ void (*printBill)(const CartItem*, int, float, float, float) = printDetailed; printBill(cart, n, grand, gst, disc); printf("\n--- Compact mode ---\n"); printBill = printCompact; /* swap โ same call */ printBill(cart, n, grand, gst, disc); return 0; }
================================================
ANANTA GROCERY STORE
Fri Jul 04 14:30:00 2026
================================================
Item Qty Amount
------------------------------------------------
Basmati Rice 1kg 3 225.00
Toor Dal 500g 2 130.00
Sunflower Oil 1L 2 280.00
Sugar 1kg 1 42.00
------------------------------------------------
Subtotal 677.00
Loyalty Discount (10%) -67.70
GST (5%) 30.47
================================================
GRAND TOTAL 639.77
================================================
Thank you for shopping with us!
================================================
--- Compact mode ---
[RECEIPT] Items:4 GST:30.47 Disc:67.70 TOTAL: Rs 639.77
calcTotal needs to return three values โ grand total, GST, and discount. C functions return only one value, so we pass float *gstOut and float *discOut as output parameters. The function writes through these pointers and the caller reads the results from gst and disc after the call.searchProduct uses strstr(shop[i].name, keyword) to find partial name matches โ type "Rice" and it finds "Basmati Rice 1kg". It returns a pointer to the found product so the caller can use it directly. restockItem takes a non-const Product* and adds to the stock directly โ and a lowStockReport walks the array printing every item where stock has fallen below the threshold.
- 1
strstr(shop[i].name, keyword)โ returns non-NULL if keyword is a substring of the name. Case-sensitive partial match. - 2Return pointer to found product โ
return &shop[i]โ caller gets direct access to the real inventory entry. No copy. - 3
restockItem(Product *p, int qty)โp->stock += qtyโ writes through pointer, updates real inventory. - 4Low stock report โ pointer walk, print every product where
stock < threshold. Returns count of low-stock items.
#include <stdio.h> #include <string.h> typedef struct{char name[30];char category[15];float price;int stock;}Product; /* Search โ partial name match via strstr Returns pointer to product or NULL */ Product* searchProduct(Product *shop, int n, const char *keyword) { printf("\nSearching for \"%s\"...\n", keyword); for (int i = 0; i < n; i++) { if (strstr(shop[i].name, keyword)) { printf(" Found: %s @ Rs %.2f (stock: %d)\n", shop[i].name, shop[i].price, shop[i].stock); return &shop[i]; /* pointer into real array */ } } printf(" Not found.\n"); return NULL; } /* Restock โ non-const pointer, modifies stock */ void restockItem(Product *p, int qty) { if (!p) { printf(" No product to restock.\n"); return; } p->stock += qty; printf(" Restocked: %s. New stock: %d\n", p->name, p->stock); } /* Low stock report โ walk and flag */ int lowStockReport(const Product *shop, int n, int threshold) { printf("\n=== LOW STOCK REPORT (below %d units) ===\n", threshold); int count = 0; for (int i = 0; i < n; i++) { if (shop[i].stock < threshold) { printf(" %-22s stock: %d [REORDER]\n", shop[i].name, shop[i].stock); count++; } } if (!count) printf(" All products well-stocked.\n"); return count; } /* Update price โ modify through pointer */ void updatePrice(Product *p, float newPrice) { if (!p) return; printf(" Price update: %s Rs %.2f โ Rs %.2f\n", p->name, p->price, newPrice); p->price = newPrice; } int main() { Product shop[] = { {"Basmati Rice 1kg", "Grains", 75.0f, 4}, {"Toor Dal 500g", "Pulses", 65.0f, 40}, {"Sunflower Oil 1L","Oils", 140.0f, 2}, {"Amul Butter 100g","Dairy", 52.0f, 7}, {"Sugar 1kg", "Essentials",42.0f,70} }; /* Search returns pointer โ use it directly */ Product *found = searchProduct(shop, 5, "Rice"); restockItem(found, 50); updatePrice(found, 79.0f); searchProduct(shop, 5, "Oil"); lowStockReport(shop, 5, 10); return 0; }
Searching for "Rice"... Found: Basmati Rice 1kg @ Rs 75.00 (stock: 4) Restocked: Basmati Rice 1kg. New stock: 54 Price update: Basmati Rice 1kg Rs 75.00 โ Rs 79.00 Searching for "Oil"... Found: Sunflower Oil 1L @ Rs 140.00 (stock: 2) === LOW STOCK REPORT (below 10 units) === Sunflower Oil 1L stock: 2 [REORDER] Amul Butter 100g stock: 7 [REORDER]
found points at the real shop[0]. Calling restockItem(found, 50) and updatePrice(found, 79.0f) modifies the actual inventory โ not a copy. This is the most efficient pattern for find-then-modify operations.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_PRODUCTS 8 #define MAX_CART 10 #define GST_RATE 0.05f #define DISC_THRESHOLD 500.0f #define DISC_RATE 0.10f #define LOW_STOCK_LIMIT 10 typedef struct { char name[30]; char category[15]; float price; int stock; } Product; typedef struct { char name[30]; float unitPrice; int qty; float subtotal; } CartItem; /* โโ DISPLAY โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */ void displayAll(const Product *s, int n) { printf("\n%-3s %-22s %-12s %7s %6s\n", "No","Product","Category","Price","Stock"); printf("%-55s\n","-------------------------------------------------------"); for(int i=0;i<n;i++){ printf("%-3d %-22s %-12s %7.2f %6d%s\n", i+1,s[i].name,s[i].category,s[i].price,s[i].stock, s[i].stock<LOW_STOCK_LIMIT?" **LOW":""); } } /* โโ ADD TO CART โโโโโโโโโโโโโโโโโโโโโโโโโโ */ int addToCart(Product *shop, int shopSz, CartItem *cart, int *cnt, int idx, int qty) { if(idx<0||idx>=shopSz){printf(" Invalid.\n");return 0;} Product *p=&shop[idx]; if(p->stock<qty){ printf(" Only %d units of %s available.\n",p->stock,p->name); return 0; } if(*cnt>=MAX_CART){printf(" Cart full.\n");return 0;} CartItem *slot=&cart[*cnt]; strncpy(slot->name,p->name,29); slot->unitPrice=p->price; slot->qty=qty; slot->subtotal=p->price*qty; p->stock-=qty; (*cnt)++; printf(" Added: %s x%d = Rs %.2f\n", slot->name,qty,slot->subtotal); return 1; } /* โโ SHOW CART โโโโโโโโโโโโโโโโโโโโโโโโโโโโ */ void showCart(const CartItem *c, int n) { if(!n){printf("\n Cart is empty.\n");return;} printf("\n--- Cart (%d items) ---\n",n); for(int i=0;i<n;i++) printf(" %-22s x%-3d Rs %.2f\n", c[i].name,c[i].qty,c[i].subtotal); } /* โโ BILLING โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */ float calcTotal(const CartItem *c,int n, float *g,float *d){ float sub=0; for(int i=0;i<n;i++) sub+=c[i].subtotal; *d=(sub>DISC_THRESHOLD)?sub*DISC_RATE:0; *g=(sub-*d)*GST_RATE; return sub-*d+*g; } void printDetailed(const CartItem *c,int n, float grand,float gst,float disc){ time_t now=time(NULL); float sub=0; printf("\n================================================\n" " ANANTA GROCERY STORE\n" " %s" "================================================\n" "%-22s %5s %10s\n" "------------------------------------------------\n", ctime(&now),"Item","Qty","Amount"); for(int i=0;i<n;i++){ printf("%-22s %5d %10.2f\n",c[i].name,c[i].qty,c[i].subtotal); sub+=c[i].subtotal; } printf("------------------------------------------------\n" "%-27s %10.2f\n","Subtotal",sub); if(disc>0) printf("%-27s %10.2f\n","Loyalty Discount (10%)",-disc); printf("%-27s %10.2f\n" "================================================\n" "%-27s %10.2f\n" "================================================\n" " Thank you for shopping with us!\n" "================================================\n", "GST (5%)",gst,"GRAND TOTAL",grand); } /* โโ SEARCH โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */ Product* searchProduct(Product *s,int n,const char *kw){ for(int i=0;i<n;i++) if(strstr(s[i].name,kw)){ printf(" Found: %s @ Rs%.2f stock:%d\n", s[i].name,s[i].price,s[i].stock); return &s[i]; } printf(" \"%s\" not found.\n",kw); return NULL; } /* โโ LOW STOCK โโโโโโโโโโโโโโโโโโโโโโโโโโโโ */ void lowStockReport(const Product *s,int n){ int cnt=0; printf("\n=== LOW STOCK REPORT ===\n"); for(int i=0;i<n;i++) if(s[i].stock<LOW_STOCK_LIMIT){ printf(" %-22s stock:%d [REORDER]\n",s[i].name,s[i].stock); cnt++; } if(!cnt)printf(" All products well-stocked.\n"); } /* โโ MENU โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */ void showMenu(){ printf("\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n" "โ ๐ ANANTA GROCERY STORE โ\n" "โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ\n" "โ 1. View all products โ\n" "โ 2. Add item to cart โ\n" "โ 3. View cart โ\n" "โ 4. Generate bill โ\n" "โ 5. Search product โ\n" "โ 6. Low stock report โ\n" "โ 7. Clear cart โ\n" "โ 8. Exit โ\n" "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n" "Choice: "); } int main() { Product shop[MAX_PRODUCTS] = { {"Basmati Rice 1kg", "Grains", 75.0f, 50}, {"Toor Dal 500g", "Pulses", 65.0f, 40}, {"Sunflower Oil 1L","Oils", 140.0f, 7}, {"Whole Wheat Atta","Grains", 55.0f, 60}, {"Amul Butter 100g","Dairy", 52.0f, 25}, {"Full Cream Milk 1L","Dairy", 68.0f, 8}, {"Turmeric Powder", "Spices", 30.0f, 80}, {"Sugar 1kg", "Essentials",42.0f, 70} }; CartItem cart[MAX_CART]; int cartCount = 0, choice; do { showMenu(); scanf("%d",&choice); getchar(); switch(choice){ case 1: displayAll(shop,MAX_PRODUCTS); break; case 2: { displayAll(shop,MAX_PRODUCTS); int idx,qty; printf("Product number: "); scanf("%d",&idx); getchar(); printf("Quantity : "); scanf("%d",&qty); getchar(); addToCart(shop,MAX_PRODUCTS,cart,&cartCount,idx-1,qty); break; } case 3: showCart(cart,cartCount); break; case 4: { if(!cartCount){printf(" Cart is empty.\n");break;} float gst,disc; float grand=calcTotal(cart,cartCount,&gst,&disc); printDetailed(cart,cartCount,grand,gst,disc); break; } case 5: { char kw[30]; printf("Search keyword: "); fgets(kw,sizeof(kw),stdin); kw[strcspn(kw,"\n")]='\0'; searchProduct(shop,MAX_PRODUCTS,kw); break; } case 6: lowStockReport(shop,MAX_PRODUCTS); break; case 7: cartCount=0; printf(" Cart cleared.\n"); break; case 8: printf(" Thank you! Goodbye.\n"); break; default: printf(" Invalid choice.\n"); } } while(choice!=8); return 0; }
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ ANANTA GROCERY STORE โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
โ 1. View all products โ
...
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Choice: 2
Product number: 1 (Basmati Rice 1kg)
Quantity : 3
Added: Basmati Rice 1kg x3 = Rs 225.00
Choice: 2
Product number: 3 (Sunflower Oil 1L)
Quantity : 2
Added: Sunflower Oil 1L x2 = Rs 280.00
Choice: 4
================================================
ANANTA GROCERY STORE
Fri Jul 04 14:30:00 2026
================================================
Item Qty Amount
------------------------------------------------
Basmati Rice 1kg 3 225.00
Sunflower Oil 1L 2 280.00
------------------------------------------------
Subtotal 505.00
Loyalty Discount (10%) -50.50
GST (5%) 22.73
================================================
GRAND TOTAL 477.23
================================================
Thank you for shopping with us!
- S1 โ Struct Design: Two separate structs โ
Productfor inventory (permanent),CartItemfor basket (per-transaction).sizeofshows exact memory. Array of structs initialised with brace notation. - S2 โ const Struct Pointer:
const Product *shopโ read-only walk. Compiler blocks accidental writes. Category filter viastrcmp+continue. Low-stock alert in same loop pass. - S3 โ Pointer Modify:
addToCarttakes non-constProduct*to reduce stock andCartItem*to fill slot.int *cartCountโ pass address to let function increment caller's counter. Both arrays modified in one call. - S4 โ Bill + Function Pointer:
calcTotalreturns grand total and writes GST + discount via output pointers.void (*printBill)(...)holds eitherprintDetailedorprintCompact. Swap by reassigning โ same call, different output. - S5 โ Search + Return Pointer:
strstr(name, keyword)for partial match.return &shop[i]โ gives caller pointer into real array. Modifying through returned pointer changes actual inventory.lowStockReportusesconstpointer for read-only walk. - S6 โ Full Program:
do-whilemenu loop.getchar()clears input buffer afterscanf. Stock persists across menu choices โ same array throughout. Cart cleared by resettingcartCount = 0โ no need to zero the data.