C语言如何设计高效实验设备管理系统?

99ANYc3cd6
预计阅读时长 56 分钟
位置: 首页 C语言 正文

设计思路

我们将采用模块化的设计思想,将整个系统分解为几个核心功能模块,每个模块由不同的函数实现。

实验设备管理系统设计c语言
(图片来源网络,侵删)
  1. 数据结构设计

    • 使用 struct 来定义“设备”这个核心实体,一个设备应该包含哪些信息?ID、名称、类型、状态(可用、借出、维修中)、借用人、借出日期、归还日期等。
    • 使用一个结构体数组来存储所有设备信息。
  2. 功能模块划分

    • 主菜单:程序的入口,提供所有功能选项的导航。
    • 设备录入:向系统中添加新的设备。
    • 设备查询:根据不同条件(如ID、名称、状态)查找设备。
    • 设备借出:修改设备状态为“借出”,并记录借用人信息。
    • 设备归还:修改设备状态为“可用”,并清除借出信息。
    • 设备信息修改:更新已有设备的信息(如名称、类型)。
    • 设备删除:从系统中移除一个设备。
    • 设备列表显示:以表格形式列出所有设备。
    • 数据持久化:将设备信息保存到文件中,并在程序启动时从文件加载。
  3. 用户交互

    • 使用 printfscanf 来实现与用户的交互,为了更好的体验,可以封装一个 getInput 函数来处理输入,防止缓冲区溢出等问题。

代码实现

下面是一个完整的C语言实现,包含了详细的注释。

实验设备管理系统设计c语言
(图片来源网络,侵删)

头文件和宏定义

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h> // 用于获取当前日期
// --- 宏定义 ---
#define MAX_NAME_LEN 50
#define MAX_TYPE_LEN 30
#define MAX_USER_LEN 30
#define MAX_DEVICES 100
#define FILENAME "devices.dat"
// --- 设备状态枚举 ---
typedef enum {
    AVAILABLE,   // 0 - 可用
    BORROWED,    // 1 - 借出
    UNDER_REPAIR // 2 - 维修中
} DeviceStatus;
// --- 设备结构体 ---
typedef struct {
    int id;                         // 设备ID
    char name[MAX_NAME_LEN];        // 设备名称
    char type[MAX_TYPE_LEN];        // 设备类型
    DeviceStatus status;            // 设备状态
    char borrower[MAX_USER_LEN];     // 借用人
    char borrow_date[20];            // 借出日期 (YYYY-MM-DD)
    char return_date[20];           // 归还日期 (YYYY-MM-DD)
} Device;
// --- 全局变量 ---
Device devices[MAX_DEVICES]; // 设备数组
int device_count = 0;       // 当前设备数量
// --- 函数声明 ---
void loadDevicesFromFile();
void saveDevicesToFile();
void showMainMenu();
void addDevice();
void listDevices();
void searchDevices();
void borrowDevice();
void returnDevice();
void modifyDevice();
void deleteDevice();
void clearInputBuffer();

核心功能函数实现

// 从文件加载设备数据
void loadDevicesFromFile() {
    FILE *file = fopen(FILENAME, "rb");
    if (file == NULL) {
        // 文件不存在是正常情况(首次运行)
        return;
    }
    // 读取设备数量
    fread(&device_count, sizeof(int), 1, file);
    // 读取所有设备数据
    fread(devices, sizeof(Device), device_count, file);
    fclose(file);
}
// 将设备数据保存到文件
void saveDevicesToFile() {
    FILE *file = fopen(FILENAME, "wb");
    if (file == NULL) {
        printf("错误:无法打开文件进行保存!\n");
        return;
    }
    // 先写入设备数量
    fwrite(&device_count, sizeof(int), 1, file);
    // 再写入所有设备数据
    fwrite(devices, sizeof(Device), device_count, file);
    fclose(file);
}
// 显示主菜单
void showMainMenu() {
    system("cls || clear"); // 清屏 (Windows: cls, Linux/Mac: clear)
    printf("\n\n========== 实验设备管理系统 ==========\n");
    printf("  1. 添加新设备\n");
    printf("  2. 查看所有设备\n");
    printf("  3. 查询设备\n");
    printf("  4. 借出设备\n");
    printf("  5. 归还设备\n");
    printf("  6. 修改设备信息\n");
    printf("  7. 删除设备\n");
    printf("  0. 退出系统\n");
    printf("=====================================\n");
    printf("请输入您的选择: ");
}
// 添加新设备
void addDevice() {
    if (device_count >= MAX_DEVICES) {
        printf("设备数量已达上限,无法添加!\n");
        return;
    }
    Device new_device;
    printf("\n--- 添加新设备 ---\n");
    printf("请输入设备ID: ");
    scanf("%d", &new_device.id);
    clearInputBuffer();
    // 检查ID是否已存在
    for (int i = 0; i < device_count; i++) {
        if (devices[i].id == new_device.id) {
            printf("错误:设备ID已存在!\n");
            return;
        }
    }
    printf("请输入设备名称: ");
    fgets(new_device.name, MAX_NAME_LEN, stdin);
    new_device.name[strcspn(new_device.name, "\n")] = 0; // 去掉换行符
    printf("请输入设备类型: ");
    fgets(new_device.type, MAX_TYPE_LEN, stdin);
    new_device.type[strcspn(new_device.type, "\n")] = 0;
    new_device.status = AVAILABLE;
    strcpy(new_device.borrower, "");
    strcpy(new_device.borrow_date, "");
    strcpy(new_device.return_date, "");
    devices[device_count++] = new_device;
    printf("设备添加成功!\n");
    saveDevicesToFile();
}
// 显示所有设备
void listDevices() {
    if (device_count == 0) {
        printf("\n当前没有任何设备记录,\n");
        return;
    }
    printf("\n--- 所有设备列表 ---\n");
    printf("+----+----------------------+----------------------+--------+----------------------+----------------------+----------------------+\n");
    printf("| ID | 名称                 | 类型                 | 状态   | 借用人               | 借出日期             | 归还日期             |\n");
    printf("+----+----------------------+----------------------+--------+----------------------+----------------------+----------------------+\n");
    for (int i = 0; i < device_count; i++) {
        printf("| %2d | %-20s | %-20s | ", devices[i].id, devices[i].name, devices[i].type);
        switch (devices[i].status) {
            case AVAILABLE:   printf(" %-6s | ", "可用"); break;
            case BORROWED:    printf(" %-6s | ", "借出"); break;
            case UNDER_REPAIR: printf(" %-6s | ", "维修中"); break;
        }
        printf("%-20s | %-20s | %-20s |\n", 
               devices[i].borrower, 
               devices[i].borrow_date, 
               devices[i].return_date);
    }
    printf("+----+----------------------+----------------------+--------+----------------------+----------------------+----------------------+\n");
}
// 查询设备
void searchDevices() {
    if (device_count == 0) {
        printf("\n当前没有任何设备记录,\n");
        return;
    }
    int choice;
    printf("\n--- 查询设备 ---\n");
    printf("1. 按ID查询\n");
    printf("2. 按名称查询\n");
    printf("3. 按状态查询\n");
    printf("请选择查询方式: ");
    scanf("%d", &choice);
    clearInputBuffer();
    printf("\n--- 查询结果 ---\n");
    int found = 0;
    for (int i = 0; i < device_count; i++) {
        int match = 0;
        switch (choice) {
            case 1: {
                int search_id;
                printf("请输入要查询的ID: ");
                scanf("%d", &search_id);
                clearInputBuffer();
                if (devices[i].id == search_id) match = 1;
                break;
            }
            case 2: {
                char search_name[MAX_NAME_LEN];
                printf("请输入要查询的名称: ");
                fgets(search_name, MAX_NAME_LEN, stdin);
                search_name[strcspn(search_name, "\n")] = 0;
                if (strstr(devices[i].name, search_name) != NULL) match = 1;
                break;
            }
            case 3: {
                DeviceStatus search_status;
                printf("请选择状态 (0-可用, 1-借出, 2-维修中): ");
                scanf("%d", (int*)&search_status);
                clearInputBuffer();
                if (devices[i].status == search_status) match = 1;
                break;
            }
            default:
                printf("无效的选择!\n");
                return;
        }
        if (match) {
            if (!found) {
                printf("+----+----------------------+----------------------+--------+----------------------+----------------------+----------------------+\n");
                printf("| ID | 名称                 | 类型                 | 状态   | 借用人               | 借出日期             | 归还日期             |\n");
                printf("+----+----------------------+----------------------+--------+----------------------+----------------------+----------------------+\n");
            }
            found = 1;
            printf("| %2d | %-20s | %-20s | ", devices[i].id, devices[i].name, devices[i].type);
            switch (devices[i].status) {
                case AVAILABLE:   printf(" %-6s | ", "可用"); break;
                case BORROWED:    printf(" %-6s | ", "借出"); break;
                case UNDER_REPAIR: printf(" %-6s | ", "维修中"); break;
            }
            printf("%-20s | %-20s | %-20s |\n", 
                   devices[i].borrower, 
                   devices[i].borrow_date, 
                   devices[i].return_date);
        }
    }
    if (found) {
        printf("+----+----------------------+----------------------+--------+----------------------+----------------------+----------------------+\n");
    } else {
        printf("未找到匹配的设备,\n");
    }
}
// 借出设备
void borrowDevice() {
    if (device_count == 0) {
        printf("\n当前没有任何设备记录,\n");
        return;
    }
    int id;
    printf("\n--- 借出设备 ---\n");
    printf("请输入要借出的设备ID: ");
    scanf("%d", &id);
    clearInputBuffer();
    for (int i = 0; i < device_count; i++) {
        if (devices[i].id == id) {
            if (devices[i].status == AVAILABLE) {
                devices[i].status = BORROWED;
                printf("请输入借用人姓名: ");
                fgets(devices[i].borrower, MAX_USER_LEN, stdin);
                devices[i].borrower[strcspn(devices[i].borrower, "\n")] = 0;
                // 获取当前日期
                time_t t = time(NULL);
                struct tm tm = *localtime(&t);
                sprintf(devices[i].borrow_date, "%d-%02d-%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
                strcpy(devices[i].return_date, ""); // 归还日期先为空
                printf("设备借出成功!\n");
                printf("借出日期: %s\n", devices[i].borrow_date);
                saveDevicesToFile();
            } else {
                printf("该设备当前不可用(状态: %s),\n", 
                       devices[i].status == BORROWED ? "已借出" : "维修中");
            }
            return;
        }
    }
    printf("未找到ID为 %d 的设备,\n", id);
}
// 归还设备
void returnDevice() {
    if (device_count == 0) {
        printf("\n当前没有任何设备记录,\n");
        return;
    }
    int id;
    printf("\n--- 归还设备 ---\n");
    printf("请输入要归还的设备ID: ");
    scanf("%d", &id);
    clearInputBuffer();
    for (int i = 0; i < device_count; i++) {
        if (devices[i].id == id) {
            if (devices[i].status == BORROWED) {
                devices[i].status = AVAILABLE;
                // 获取当前日期作为归还日期
                time_t t = time(NULL);
                struct tm tm = *localtime(&t);
                sprintf(devices[i].return_date, "%d-%02d-%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
                printf("设备归还成功!\n");
                printf("归还日期: %s\n", devices[i].return_date);
                // 清空借用人信息
                strcpy(devices[i].borrower, "");
                strcpy(devices[i].borrow_date, "");
                saveDevicesToFile();
            } else {
                printf("该设备未被借出或状态不正确,\n");
            }
            return;
        }
    }
    printf("未找到ID为 %d 的设备,\n", id);
}
// 修改设备信息
void modifyDevice() {
    if (device_count == 0) {
        printf("\n当前没有任何设备记录,\n");
        return;
    }
    int id;
    printf("\n--- 修改设备信息 ---\n");
    printf("请输入要修改的设备ID: ");
    scanf("%d", &id);
    clearInputBuffer();
    for (int i = 0; i < device_count; i++) {
        if (devices[i].id == id) {
            printf("找到设备: %s (ID: %d)\n", devices[i].name, devices[i].id);
            printf("请输入新的设备名称 (当前: %s): ", devices[i].name);
            fgets(devices[i].name, MAX_NAME_LEN, stdin);
            devices[i].name[strcspn(devices[i].name, "\n")] = 0;
            printf("请输入新的设备类型 (当前: %s): ", devices[i].type);
            fgets(devices[i].type, MAX_TYPE_LEN, stdin);
            devices[i].type[strcspn(devices[i].type, "\n")] = 0;
            printf("设备信息修改成功!\n");
            saveDevicesToFile();
            return;
        }
    }
    printf("未找到ID为 %d 的设备,\n", id);
}
// 删除设备
void deleteDevice() {
    if (device_count == 0) {
        printf("\n当前没有任何设备记录,\n");
        return;
    }
    int id;
    printf("\n--- 删除设备 ---\n");
    printf("请输入要删除的设备ID: ");
    scanf("%d", &id);
    clearInputBuffer();
    for (int i = 0; i < device_count; i++) {
        if (devices[i].id == id) {
            // 确认是否真的要删除
            printf("您确定要删除设备 '%s' (ID: %d) 吗? (y/n): ", devices[i].name, devices[i].id);
            char confirm;
            scanf(" %c", &confirm);
            if (confirm == 'y' || confirm == 'Y') {
                // 将最后一个元素移到当前位置,然后减少数量
                devices[i] = devices[device_count - 1];
                device_count--;
                printf("设备删除成功!\n");
                saveDevicesToFile();
            } else {
                printf("删除操作已取消,\n");
            }
            return;
        }
    }
    printf("未找到ID为 %d 的设备,\n", id);
}
// 清空输入缓冲区
void clearInputBuffer() {
    while (getchar() != '\n');
}
// 主函数
int main() {
    loadDevicesFromFile(); // 程序启动时加载数据
    int choice;
    do {
        showMainMenu();
        scanf("%d", &choice);
        clearInputBuffer();
        switch (choice) {
            case 1: addDevice(); break;
            case 2: listDevices(); break;
            case 3: searchDevices(); break;
            case 4: borrowDevice(); break;
            case 5: returnDevice(); break;
            case 6: modifyDevice(); break;
            case 7: deleteDevice(); break;
            case 0: printf("感谢使用,再见!\n"; break;
            default: printf("无效的输入,请重新选择!\n");
        }
        if (choice != 0) {
            printf("\n按 Enter 键返回主菜单...");
            getchar(); // 等待用户按回车
        }
    } while (choice != 0);
    return 0;
}

如何运行和扩展

如何运行

  1. 将以上代码保存为一个文件,device_manager.c
  2. 使用GCC编译器进行编译:
    gcc device_manager.c -o device_manager
  3. 运行生成的可执行文件:
    • 在Windows上: device_manager.exe
    • 在Linux或macOS上: ./device_manager

系统功能说明

  • 数据持久化:程序运行时,数据存储在内存中,当选择退出(选项0)时,所有数据会自动保存到 devices.dat 文件中,下次启动程序时,会自动从该文件加载数据。
  • 借出/归还逻辑:借出设备时,系统会自动记录当前日期作为借出日期,归还设备时,会自动记录归还日期,并将设备状态重置为“可用”。
  • 用户输入处理clearInputBuffer() 函数用于处理 scanf 后可能留在输入缓冲区中的换行符,防止后续的 fgetsgetchar 出现问题。

如何扩展和改进

这个系统是一个基础版本,可以根据需要进行扩展:

  1. 更复杂的查询:增加按“借用人”查询、按“借出日期范围”查询等功能。
  2. 用户权限管理:增加“管理员”和“普通用户”角色,普通用户只能查询和借还设备,管理员才能进行增删改操作。
  3. 图形用户界面:使用GTK、Qt等库为程序创建图形界面,提升用户体验。
  4. 数据库支持:对于大量设备数据,使用文件存储可能效率不高,可以改用SQLite等轻量级数据库,它无需单独的服务器,非常适合此类应用。
  5. 数据校验:在输入设备ID、日期等时,增加更严格的格式校验,防止非法输入。
  6. 统计报表功能:增加统计功能,本月借出次数最多的设备”、“当前在借设备数量”等。
实验设备管理系统设计c语言
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
dede首页留言板如何正确设置与使用?
« 上一篇 03-12
dede文章页如何调用频道信息?
下一篇 » 03-12

相关文章

取消
微信二维码
支付宝二维码

目录[+]