【C语言】药店药品管理系统 -丨完整源码与实现解析

发布于:2025-06-21 ⋅ 阅读:(19) ⋅ 点赞:(0)

 系统概述

这是一个功能完善的药店药品管理系统,使用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 文件中
  • 每次启动程序时会自动加载之前保存的数据
  • 退出程序时自动保存当前数据

功能操作

  1. 添加药品​:输入药品编号、名称、单价和库存量
  2. 删除药品​:根据药品编号删除指定药品
  3. 修改药品​:更新药品的名称、单价和库存
  4. 查询药品​:支持按编号或名称进行模糊查询
  5. 排序功能​:按价格或库存进行降序排列
  6. 数据保存​:手动保存当前数据到文件
  7. 退出系统​:安全退出并保存数据

关键实现要点

  1. 数据结构选择​:

    • 使用单链表存储药品信息
    • 动态内存分配管理药品节点
    • 全局头指针和计数器简化管理
  2. 数据持久化​:

    • 使用二进制文件格式提高存储效率
    • fread/fwrite实现结构体直接读写
    • 自动加载和保存机制确保数据安全
  3. 用户交互设计​:

    • 清晰的菜单导航系统
    • 表格化数据显示
    • 输入错误处理和缓冲区清理
  4. 排序算法​:

    • 冒泡排序实现简单高效
    • 仅交换节点数据,保持链表结构
    • 支持价格和库存两种排序方式

系统总结

这个药店药品管理系统展示了C语言在数据结构、文件操作和用户界面设计方面的强大能力。通过本系统,您可以:

  1. 了解链表数据结构的实际应用
  2. 掌握C语言文件操作技巧
  3. 学习完整项目的基本架构设计
  4. 掌握用户界面的基本设计原则
  5. 学习数据持久化存储的实现方法

系统具有良好的扩展性,可以根据需要添加更多功能,如:

  • 按销售日期管理药品
  • 添加有效期管理
  • 实现采购和销售模块
  • 添加用户登录和权限控制

代码已添加详细注释,便于理解和学习,是学习C语言编程和数据结构实现的优秀案例。

资源推荐:

C/C++学习交流君羊 << 点击加入

C/C++教程

C/C++学习路线,就业咨询,技术提升


网站公告

今日签到

点亮在社区的每一天
去签到