
As a software engineering student, I have to do something with my C program per semester. In this series semester, I worked on the Medical Store Management System in C Language. Below is the description of my project.
Firstly :
Headers, Structures, and Utility Functions
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#define MAX 100
// ---- Structures ----
struct User {
char username[30];
char password[30];
char role[10];
};
struct Medicine {
int id;
char name[50];
char company[50];
char category[30];
int quantity;
float price;
char expiry[15];
};
struct SaleLog {
char customer[50];
char medicine[50];
int quantity;
float total;
char date[20];
};
// ---- Utility Functions ----
void clearInputBuffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF) {}
}
void getInput(const char *prompt, char *buffer, int size) {
printf("%s", prompt);
if (fgets(buffer, size, stdin) != NULL)
buffer[strcspn(buffer, "\n")] = '\0';
}
int caseInsensitiveStrstr(const char *haystack, const char *needle) {
char h[MAX], n[MAX];
int i;
for (i = 0; haystack[i] && i < MAX-1; i)
h[i] = tolower(haystack[i]);
h[i] = 0;
for (i = 0; needle[i] && i < MAX-1; i)
n[i] = tolower(needle[i]);
n[i] = 0;
return strstr(h, n) != NULL;
}
Explanation :
Headers: Needed for input/output, strings, file handling, time, etc.
Structures:
User: stores login info.
Medicine: full info about medicines.
SaleLog: customer purchase history.
Utility Functions:
clearInputBuffer() → flush input buffer.
getInput() → safe string input.
caseInsensitiveStrstr() → search medicine name ignoring case.

Here, from the beginning user have to login to the system as a user/amin/stuff , with valid password.
After successfully login to the system you can chose what he wants to do .
Add Medicine , Update Medicine , Delete Medicine , Search , Sort , Billing , Sales Report , Check low stock and Expiry , Change Password , Backup , Restore , Logout .
User Management
char currentUser[30] = "";
char currentRole[10] = "";
// ---- Function Declarations ----
void registerUser();
void login();
void logout();
void changePassword(const char username[]);
void logSession(const char username[], const char mode[]);
int isAdmin();
int isStaff();
// ---- Implementations ----
void registerUser() {
FILE *fp = fopen("use.txt", "a");
struct User u;
if (fp == NULL) {
printf("Error opening file!\n");
return;
}
printf("\n--- Register (First Time) ---\n");
printf("Enter username (no space): ");
scanf("%29s", u.username);
clearInputBuffer();
printf("Enter password (no space): ");
scanf("%29s", u.password);
clearInputBuffer();
do {
printf("Enter role (admin/staff): ");
scanf("%9s", u.role);
clearInputBuffer();
} while (strcmp(u.role, "admin") != 0 && strcmp(u.role, "staff") != 0);
fprintf(fp, "%s %s %s\n", u.username, u.password, u.role);
fclose(fp);
printf("User registered successfully!\n");
}
void login() {
FILE *fp;
struct User u;
char uname[30], pass[30];
int found = 0;
fp = fopen("use.txt", "r");
if (!fp || fgetc(fp) == EOF) {
if (fp) fclose(fp);
registerUser();
} else fclose(fp);
while (!found) {
fp = fopen("use.txt", "r");
if (!fp) {
printf("Error opening user file.\n");
exit(1);
}
printf("\nLogin\nUsername: ");
scanf("%29s", uname);
clearInputBuffer();
printf("Password: ");
scanf("%29s", pass);
clearInputBuffer();
while (fscanf(fp, "%29s %29s %9s", u.username, u.password, u.role) == 3) {
if (strcmp(u.username, uname) == 0 && strcmp(u.password, pass) == 0) {
strcpy(currentUser, uname);
strcpy(currentRole, u.role);
logSession(uname, "login");
printf("Login successful!\n");
found = 1;
break;
}
}
fclose(fp);
if (!found) printf("Invalid username or password. Try again.\n");
}
}
void logout() {
logSession(currentUser, "logout");
printf("Logged out successfully.\n");
}
void logSession(const char username[], const char mode[]) {
FILE *fp = fopen("session_log.txt", "a");
if (!fp) return;
time_t now = time(NULL);
fprintf(fp, "%s %s at %s", username, mode, ctime(&now));
fclose(fp);
}
void changePassword(const char username[]) {
FILE *fp = fopen("use.txt", "r");
struct User users[100];
int count = 0, found = 0;
char newPass[30];
if (!fp) {
printf("User file not found.\n");
return;
}
while (fscanf(fp, "%29s %29s %9s", users[count].username,
users[count].password, users[count].role) == 3) {
count++;
}
fclose(fp);
printf("Enter new password (no space): ");
scanf("%29s", newPass);
clearInputBuffer();
for (int i = 0; i < count; i++) {
if (strcmp(users[i].username, username) == 0) {
strcpy(users[i].password, newPass);
found = 1;
break;
}
}
if (!found) {
printf("User not found.\n");
return;
}
fp = fopen("use.txt", "w");
for (int i = 0; i < count; i++) {
fprintf(fp, "%s %s %s\n", users[i].username,
users[i].password, users[i].role);
}
fclose(fp);
printf("Password updated successfully.\n");
}
int isAdmin() { return strcmp(currentRole, "admin") == 0; }
int isStaff() { return strcmp(currentRole, "staff") == 0; }
## Explanation
registerUser() → Creates new admin/staff account.
login() → Validates user credentials.
logout() → Ends session and logs it.
changePassword() → Lets users update password.
isAdmin()/isStaff() → Role-based access control.
Medicine Management
// ---- Function Declarations ----
int getUniqueMedicineID();
void addMedicine();
void updateMedicine();
void deleteMedicine();
void searchMedicine();
void sortMedicines();
void checkLowStock();
void checkExpiry();
// ---- Implementations ----
int getUniqueMedicineID() {
int id;
FILE *fp = fopen("medicines.txt", "r");
struct Medicine med;
int unique = 1;
do {
unique = 1;
printf("Enter Medicine ID: ");
if (scanf("%d", &id) != 1) {
clearInputBuffer();
printf("Invalid input! Please enter a number.\n");
continue;
}
clearInputBuffer();
if (fp) {
rewind(fp);
while (fscanf(fp, "%d|%49[|]|%49[|]|%f|%29[|]|%d|%14[\n]\n",
&med.id, med.name, med.company, &med.price,
med.category, &med.quantity, med.expiry) == 7) {
if (med.id == id) {
unique = 0;
printf("This ID already exists! Try another.\n");
break;
}
}
}
} while (!unique);
if (fp) fclose(fp);
return id;
}
void addMedicine() {
FILE *fp = fopen("medicines.txt", "a");
struct Medicine med;
if (!fp) { printf("Error opening medicine file.\n"); return; }
printf("\n<<<< Add Medicine >>>>\n");
med.id = getUniqueMedicineID();
getInput("Medicine Name: ", med.name, sizeof(med.name));
getInput("Company: ", med.company, sizeof(med.company));
printf("Price: ");
while (scanf("%f", &med.price) != 1) {
clearInputBuffer();
printf("Invalid input! Enter Price: ");
}
clearInputBuffer();
getInput("Category: ", med.category, sizeof(med.category));
printf("Quantity: ");
while (scanf("%d", &med.quantity) != 1) {
clearInputBuffer();
printf("Invalid input! Enter Quantity: ");
}
clearInputBuffer();
getInput("Expiry Date (dd-mm-yyyy): ", med.expiry, sizeof(med.expiry));
fprintf(fp, "%d|%s|%s|%.2f|%s|%d|%s\n", med.id, med.name, med.company,
med.price, med.category, med.quantity, med.expiry);
fclose(fp);
printf("Medicine added successfully!\n");
}
// (updateMedicine(), deleteMedicine(), searchMedicine(),
// sortMedicines(), checkLowStock(), checkExpiry() implemented here)
// (Already written in your original program)
Explanation
getUniqueMedicineID() → Ensures unique IDs.
addMedicine() → Add new medicine.
updateMedicine() → Modify stock & price.
deleteMedicine() → Remove medicine by ID.
searchMedicine() → Case-insensitive search.
sortMedicines() → Sorts medicines alphabetically.
checkLowStock() → Detect low stock.
checkExpiry() → Detect expired medicines.
Billing & Sales Report
// ---- Function Declarations ----
void billing();
void salesReport();
// ---- Implementations ----
void billing() {
FILE *fp = fopen("medicines.txt", "r");
FILE *temp = fopen("temp_medicines.txt", "w");
FILE *sales = fopen("sales.txt", "a");
struct Medicine med;
struct SaleLog s;
int id, qty, found = 0;
char line[256];
time_t t = time(NULL);
struct tm tm = *localtime(&t);
if (!fp || !temp || !sales) {
printf("Error opening file(s).\n");
if (fp) fclose(fp);
if (temp) fclose(temp);
if (sales) fclose(sales);
return;
}
getInput("Customer Name: ", s.customer, sizeof(s.customer));
printf("Medicine ID for sell: ");
while (scanf("%d", &id) != 1) { printf("Enter valid number!\n"); clearInputBuffer(); }
clearInputBuffer();
printf("Quantity: ");
while (scanf("%d", &qty) != 1) { printf("Enter valid number!\n"); clearInputBuffer(); }
clearInputBuffer();
while (fgets(line, sizeof(line), fp)) {
int res = sscanf(line, "%d|%49[^|]|%49[^|]|%f|%29[^|]|%d|%14[^\n]",
&med.id, med.name, med.company, &med.price,
med.category, &med.quantity, med.expiry);
if (res != 7) { fputs(line, temp); continue; }
if (med.id == id) {
found = 1;
if (med.quantity >= qty) {
med.quantity -= qty;
s.quantity = qty;
strcpy(s.medicine, med.name);
s.total = med.price * qty;
sprintf(s.date, "%02d-%02d-%04d", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
fprintf(sales, "%s|%s|%d|%.2f|%s\n", s.customer, s.medicine, s.quantity, s.total, s.date);
printf("Bill: %.2f\n", s.total);
} else {
printf("Not enough stock!\n");
}
}
fprintf(temp, "%d|%s|%s|%.2f|%s|%d|%s\n",
med.id, med.name, med.company, med.price,
med.category, med.quantity, med.expiry);
}
fclose(fp); fclose(temp); fclose(sales);
if (!found) {
printf("Medicine Not Found!\n");
remove("temp_medicines.txt");
} else {
remove("medicines.txt");
rename("temp_medicines.txt", "medicines.txt");
}
}
void salesReport() {
FILE *fp = fopen("sales.txt", "r");
if (!fp) { printf("Error opening sales file.\n"); return; }
printf("\n --- Sales Report ---\n");
char line[256];
struct SaleLog s;
while (fgets(line, sizeof(line), fp)) {
int ok = sscanf(line, "%49[|]|%49[|]|%d|%f|%19[^\n]",
s.customer, s.medicine, &s.quantity, &s.total, s.date);
if (ok == 5) {
printf("Customer: %s | Medicine: %s | Qty: %d | Total: %.2f | Date: %s\n",
s.customer, s.medicine, s.quantity, s.total, s.date);
}
}
fclose(fp);
}
## Explanation
billing() → Handles medicine sale, updates stock, records sale.
salesReport() → Displays history of all sales.
# Backup, Restore, and Main Menu
// ---- Backup & Restore ----
void backup() {
FILE *src, *dst;
char line[512];
src = fopen("medicines.txt", "r");
dst = fopen("medicines_backup.txt", "w");
if (!src || !dst) { printf("Error opening files for medicine backup.\n"); return; }
while (fgets(line, sizeof(line), src)) fputs(line, dst);
fclose(src); fclose(dst);
src = fopen("sales.txt", "r");
dst = fopen("sales_backup.txt", "w");
if (!src || !dst) { printf("Error opening files for sales backup.\n"); return; }
while (fgets(line, sizeof(line), src)) fputs(line, dst);
fclose(src); fclose(dst);
printf("Backup Completed Successfully.\n");
}
void restore() {
FILE *src, *dst;
char line[512];
src = fopen("medicines_backup.txt", "r");
dst = fopen("medicines.txt", "w");
if (!src || !dst) { printf("Error opening Medicine Backup files.\n"); return; }
while (fgets(line, sizeof(line), src)) fputs(line, dst);
fclose(src); fclose(dst);
src = fopen("sales_backup.txt", "r");
dst = fopen("sales.txt", "w");
if (!src || !dst) { printf("Error opening Sales Backup files.\n"); return; }
while (fgets(line, sizeof(line), src)) fputs(line, dst);
fclose(src); fclose(dst);
printf("Restore Completed Successfully!\n");
}
// ---- Main Function ----
int main() {
int choice;
login();
while (1) {
printf("\n||------- Medical Store System Menu -------||\n");
if (isAdmin()) {
printf("1. Add Medicine\n2. Update Medicine\n3. Delete Medicine\n4. Search Medicine\n");
printf("5. Sort Medicines\n6. Billing\n7. Sales Report\n8. Check Low Stock\n9. Check Expiry\n");
printf("10. Change Password\n11. Backup\n12. Restore\n13. Logout\n");
} else if (isStaff()) {
printf("1. Search Medicine\n2. Sort Medicines\n3. Billing\n4. Check Low Stock\n");
printf("5. Change Password\n6. Logout\n");
} else {
printf("Role not recognized. Exiting.\n");
exit(1);
}
printf("Enter choice: ");
if (scanf("%d", &choice) != 1) {
clearInputBuffer();
printf("Invalid input! Please enter a number.\n");
continue;
}
clearInputBuffer();
if (isAdmin()) {
switch (choice) {
case 1: addMedicine(); break;
case 2: updateMedicine(); break;
case 3: deleteMedicine(); break;
case 4: searchMedicine(); break;
case 5: sortMedicines(); break;
case 6: billing(); break;
case 7: salesReport(); break;
case 8: checkLowStock(); break;
case 9: checkExpiry(); break;
case 10: changePassword(currentUser); break;
case 11: backup(); break;
case 12: restore(); break;
case 13: logout(); exit(0);
default: printf("Invalid choice.\n");
}
} else if (isStaff()) {
switch (choice) {
case 1: searchMedicine(); break;
case 2: sortMedicines(); break;
case 3: billing(); break;
case 4: checkLowStock(); break;
case 5: changePassword(currentUser); break;
case 6: logout(); exit(0);
default: printf("Invalid choice.\n");
}
}
}
return 0;
}
# Explanation
backup() → Creates backup of medicines & sales.
restore() → Restores data from backup.
main():
Starts with login.
Admin has full menu (CRUD + Billing + Reports + Backup).
Staff has limited menu.
Uses infinite loop until
Billing & Sales Report
// ---- Function Declarations ----
Explanationid billing() {
billing() → Handles medicine sale, updates stock, records sale.
salesReport() → Displays history of all sales.
void billing();
void salesReport();
// ---- Implementations ----
vo
FILE *fp = fopen("medicines.txt", "r");
FILE *temp = fopen("temp_medicines.txt", "w");
FILE *sales = fopen("sales.txt", "a");
struct Medicine med;
struct SaleLog s;
int id, qty, found = 0;
char line[256];
time_t t = time(NULL);
struct tm tm = *localtime(&t);
if (!fp || !temp || !sales) {
printf("Error opening file(s).\n");
if (fp) fclose(fp);
if (temp) fclose(temp);
if (sales) fclose(sales);
return;
}
getInput("Customer Name: ", s.customer, sizeof(s.customer));
printf("Medicine ID for sell: ");
while (scanf("%d", &id) != 1) { printf("Enter valid number!\n"); clearInputBuffer(); }
clearInputBuffer();
printf("Quantity: ");
while (scanf("%d", &qty) != 1) { printf("Enter valid number!\n"); clearInputBuffer(); }
clearInputBuffer();
while (fgets(line, sizeof(line), fp)) {
int res = sscanf(line, "%d|%49[^|]|%49[^|]|%f|%29[^|]|%d|%14[^\n]",
&med.id, med.name, med.company, &med.price,
med.category, &med.quantity, med.expiry);
if (res != 7) { fputs(line, temp); continue; }
if (med.id == id) {
found = 1;
if (med.quantity >= qty) {
med.quantity -= qty;
s.quantity = qty;
strcpy(s.medicine, med.name);
s.total = med.price * qty;
sprintf(s.date, "%02d-%02d-%04d", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
fprintf(sales, "%s|%s|%d|%.2f|%s\n", s.customer, s.medicine, s.quantity, s.total, s.date);
printf("Bill: %.2f\n", s.total);
} else {
printf("Not enough stock!\n");
}
}
fprintf(temp, "%d|%s|%s|%.2f|%s|%d|%s\n",
med.id, med.name, med.company, med.price,
med.category, med.quantity, med.expiry);
}
fclose(fp); fclose(temp); fclose(sales);
if (!found) {
printf("Medicine Not Found!\n");
remove("temp_medicines.txt");
} else {
remove("medicines.txt");
rename("temp_medicines.txt", "medicines.txt");
}
}
void salesReport() {
FILE *fp = fopen("sales.txt", "r");
if (!fp) { printf("Error opening sales file.\n"); return; }
printf("\n --- Sales Report ---\n");
char line[256];
struct SaleLog s;
while (fgets(line, sizeof(line), fp)) {
int ok = sscanf(line, "%49[|]|%49[|]|%d|%f|%19[^\n]",
s.customer, s.medicine, &s.quantity, &s.total, s.date);
if (ok == 5) {
printf("Customer: %s | Medicine: %s | Qty: %d | Total: %.2f | Date: %s\n",
s.customer, s.medicine, s.quantity, s.total, s.date);
}
}
fclose(fp);
}
USER MANUAL
USER interface

Amin Login

Normal Login interface

Add Medicine

Delete Medicine

Update Medicine

Expiary info

stock CK

Billing info

***THANKS ***