系统概述
这是一个功能完善的药店药品管理系统,使用C语言开发,基于链表数据结构实现。系统提供药品信息的增删改查、排序和持久化存储功能,适用于药店日常药品管理工作。
数据结构设计
#define MAX_NAME_LEN 50
#define MAX_ID_LEN 20
#define FILENAME "medicine.dat"/* 药品信息结构体 */
typedef struct Medicine {char id[MAX_ID_LEN]; // 药品编号char name[MAX_NAME_LEN]; // 药品名称float price; // 单价int stock; // 库存数量struct Medicine *next; // 链表指针
} Medicine;
系统核心函数
1. 链表初始化与持久化
/* 从文件加载数据 */
void loadFromFile() {FILE *file = fopen(FILENAME, "rb");if (!file) return;Medicine temp;while (fread(&temp, sizeof(Medicine), 1, file)) {Medicine *newMed = (Medicine*)malloc(sizeof(Medicine));*newMed = temp;newMed->next = head;head = newMed;medicineCount++;}fclose(file);
}/* 保存数据到文件 */
void saveToFile() {FILE *file = fopen(FILENAME, "wb");if (!file) {printf("无法打开文件进行保存!\n");return;}Medicine *current = head;while (current) {fwrite(current, sizeof(Medicine), 1, file);current = current->next;}fclose(file);printf("成功保存%d条药品记录!\n", medicineCount);
}
2. 药品添加功能
void addMedicine() {Medicine *newMed = (Medicine*)malloc(sizeof(Medicine));printf("\n--- 添加新药品 ---\n");// 输入药品编号并检查重复printf("输入药品编号: ");scanf("%s", newMed->id);clearInputBuffer();Medicine *current = head;while (current) {if (strcmp(current->id, newMed->id) == 0) {printf("错误:药品编号已存在!\n");free(newMed);return;}current = current->next;}// 输入其他信息printf("输入药品名称: ");fgets(newMed->name, MAX_NAME_LEN, stdin);newMed->name[strcspn(newMed->name, "\n")] = '\0';printf("输入药品单价: ");scanf("%f", &newMed->price);printf("输入库存数量: ");scanf("%d", &newMed->stock);clearInputBuffer();// 添加到链表头部newMed->next = head;head = newMed;medicineCount++;printf("药品添加成功!\n");
}
3. 药品删除功能
void deleteMedicine() {char id[MAX_ID_LEN];printf("\n--- 删除药品 ---\n");printf("输入要删除的药品编号: ");scanf("%s", id);clearInputBuffer();Medicine *current = head;Medicine *prev = NULL;while (current) {if (strcmp(current->id, id) == 0) {if (prev) {prev->next = current->next;} else {head = current->next;}free(current);medicineCount--;printf("药品删除成功!\n");return;}prev = current;current = current->next;}printf("未找到该药品!\n");
}
4. 药品查询功能
void searchMedicine() {char keyword[MAX_NAME_LEN];int found = 0;printf("\n--- 药品查询 ---\n");printf("输入药品编号或名称: ");fgets(keyword, MAX_NAME_LEN, stdin);keyword[strcspn(keyword, "\n")] = '\0';Medicine *current = head;printf("\n%-15s %-20s %-10s %-10s\n", "编号", "名称", "单价", "库存");printf("------------------------------------------------\n");while (current) {if (strstr(current->id, keyword) || strstr(current->name, keyword)) {printf("%-15s %-20s %-10.2f %-10d\n", current->id, current->name, current->price, current->stock);found = 1;}current = current->next;}if (!found) {printf("未找到匹配的药品!\n");}
}
5. 排序功能实现
/* 按价格排序(冒泡排序) */
void sortByPrice() {if (!head || !head->next) return;int swapped;Medicine *ptr1;Medicine *lptr = NULL;do {swapped = 0;ptr1 = head;while (ptr1->next != lptr) {if (ptr1->price < ptr1->next->price) {// 交换节点数据Medicine temp = *ptr1;strcpy(ptr1->id, ptr1->next->id);strcpy(ptr1->name, ptr1->next->name);ptr1->price = ptr1->next->price;ptr1->stock = ptr1->next->stock;strcpy(ptr1->next->id, temp.id);strcpy(ptr1->next->name, temp.name);ptr1->next->price = temp.price;ptr1->next->stock = temp.stock;swapped = 1;}ptr1 = ptr1->next;}lptr = ptr1;} while (swapped);printf("\n已按价格降序排序!\n");displayAll();
}
完整系统源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>#define MAX_NAME_LEN 50
#define MAX_ID_LEN 20
#define FILENAME "medicine.dat"typedef struct Medicine {char id[MAX_ID_LEN];char name[MAX_NAME_LEN];float price;int stock;struct Medicine *next;
} Medicine;Medicine *head = NULL;
int medicineCount = 0;// 所有函数声明
void initSystem();
void saveToFile();
void loadFromFile();
void addMedicine();
void deleteMedicine();
void modifyMedicine();
void searchMedicine();
void displayAll();
void sortByPrice();
void sortByStock();
void clearInputBuffer();
void freeList();int main() {int choice;initSystem();while (1) {system("cls || clear");printf("\n===== 药店药品管理系统 =====\n");printf("1. 添加药品信息\n");printf("2. 删除药品信息\n");printf("3. 修改药品信息\n");printf("4. 查询药品信息\n");printf("5. 显示所有药品\n");printf("6. 按价格排序\n");printf("7. 按库存排序\n");printf("8. 保存数据\n");printf("0. 退出系统\n");printf("============================\n");printf("请选择操作: ");if (scanf("%d", &choice) != 1) {clearInputBuffer();printf("输入无效,请重新输入!\n");continue;}switch (choice) {case 1: addMedicine(); break;case 2: deleteMedicine(); break;case 3: modifyMedicine(); break;case 4: searchMedicine(); break;case 5: displayAll(); break;case 6: sortByPrice(); break;case 7: sortByStock(); break;case 8: saveToFile(); break;case 0: saveToFile();freeList();printf("系统已退出,数据已保存!\n");exit(0);default:printf("无效选择,请重新输入!\n");}printf("\n按回车键继续...");clearInputBuffer();getchar();}return 0;
}// 此处为前文列出的所有函数实现...
数据文件
- 所有药品数据自动保存到
medicine.dat
文件中 - 每次启动程序时会自动加载之前保存的数据
- 退出程序时自动保存当前数据
功能操作
- 添加药品:输入药品编号、名称、单价和库存量
- 删除药品:根据药品编号删除指定药品
- 修改药品:更新药品的名称、单价和库存
- 查询药品:支持按编号或名称进行模糊查询
- 排序功能:按价格或库存进行降序排列
- 数据保存:手动保存当前数据到文件
- 退出系统:安全退出并保存数据
关键实现要点
-
数据结构选择:
- 使用单链表存储药品信息
- 动态内存分配管理药品节点
- 全局头指针和计数器简化管理
-
数据持久化:
- 使用二进制文件格式提高存储效率
fread/fwrite
实现结构体直接读写- 自动加载和保存机制确保数据安全
-
用户交互设计:
- 清晰的菜单导航系统
- 表格化数据显示
- 输入错误处理和缓冲区清理
-
排序算法:
- 冒泡排序实现简单高效
- 仅交换节点数据,保持链表结构
- 支持价格和库存两种排序方式
系统总结
这个药店药品管理系统展示了C语言在数据结构、文件操作和用户界面设计方面的强大能力。通过本系统,您可以:
- 了解链表数据结构的实际应用
- 掌握C语言文件操作技巧
- 学习完整项目的基本架构设计
- 掌握用户界面的基本设计原则
- 学习数据持久化存储的实现方法
系统具有良好的扩展性,可以根据需要添加更多功能,如:
- 按销售日期管理药品
- 添加有效期管理
- 实现采购和销售模块
- 添加用户登录和权限控制
代码已添加详细注释,便于理解和学习,是学习C语言编程和数据结构实现的优秀案例。
资源推荐:
C/C++学习交流君羊 << 点击加入
C/C++教程
C/C++学习路线,就业咨询,技术提升