系统概述
这是一个功能完善的药店药品管理系统,使用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++学习交流君羊 << 点击加入