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 ***
You can check out this post and your own profile on the map. Be part of the Worldmappin Community and join our Discord Channel to get in touch with other travelers, ask questions or just be updated on our latest features.
Congratulations @brain-less! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)
Your next target is to reach 700 upvotes.
You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word
STOP
Check out our last posts: