【C语言】超市管理系统丨完整源码与实现解析

 通过这个完整的超市管理系统,您将掌握C语言核心数据结构与文件操作技术

设计思路与核心数据结构

本系统使用动态数组管理商品数据,支持商品增删改查文件存储数据统计功能。系统采用模块化设计,分为商品管理、文件操作和用户界面三大模块。

// 商品结构体
typedef struct {
    int id;         // 商品ID(自动生成)
    char name[50];  // 商品名称
    float price;    // 商品单价
    int stock;      // 库存数量
} Product;

// 商品列表(动态数组)
typedef struct {
    Product* data;  // 指向商品数组的指针
    int count;      // 当前商品数量
} ProductList;

完整源代码实现

1. 头文件定义 (product.h)

// product.h
#pragma once
#define NAME_LEN 50

typedef struct {
    int id;
    char name[NAME_LEN];
    float price;
    int stock;
} Product;

typedef struct {
    Product* data;
    int count;
} ProductList;

// 函数声明
void init_products(ProductList* list);
void add_product(ProductList* list);
void display_products(ProductList* list);
void modify_product(ProductList* list);
void delete_product(ProductList* list);
void search_product(ProductList* list);
void save_to_file(const char* filename, ProductList* list);
int load_from_file(const char* filename, ProductList* list);

2. 核心功能实现 (product.c)

// product.c
#include "product.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 初始化商品列表
void init_products(ProductList* list) {
    list->data = NULL;
    list->count = 0;
}

// 添加商品
void add_product(ProductList* list) {
    // 动态扩展内存
    Product* new_data = realloc(list->data, (list->count + 1) * sizeof(Product));
    if (!new_data) {
        printf("内存分配失败!\n");
        exit(EXIT_FAILURE);
    }
    
    list->data = new_data;
    list->count++;
    
    // 自动生成ID
    list->data[list->count - 1].id = list->count;
    
    // 输入商品信息
    printf("\n商品ID: %d\n", list->count);
    printf("请输入商品名称: ");
    scanf("%49s", list->data[list->count - 1].name);
    printf("请输入单价: ");
    scanf("%f", &list->data[list->count - 1].price);
    printf("请输入库存数量: ");
    scanf("%d", &list->data[list->count - 1].stock);
    
    printf("商品添加成功!\n");
}

// 显示所有商品
void display_products(ProductList* list) {
    if (list->count == 0) {
        printf("\n库存为空\n");
        return;
    }
    
    printf("\n%5s %-20s %10s %6s\n", "ID", "名称", "单价", "库存");
    printf("------------------------------------------------\n");
    
    for (int i = 0; i < list->count; i++) {
        printf("%5d %-20s %10.2f %6d\n", 
               list->data[i].id,
               list->data[i].name,
               list->data[i].price,
               list->data[i].stock);
    }
}

// 修改商品信息
void modify_product(ProductList* list) {
    if (list->count == 0) {
        printf("\n库存为空,无法修改\n");
        return;
    }
    
    int id;
    printf("\n请输入要修改的商品ID: ");
    scanf("%d", &id);
    
    if (id < 1 || id > list->count) {
        printf("无效的商品ID\n");
        return;
    }
    
    Product* product = &list->data[id - 1];
    printf("\n当前商品信息:\n");
    printf("名称: %s, 单价: %.2f, 库存: %d\n", 
           product->name, product->price, product->stock);
    
    printf("\n输入新名称: ");
    scanf("%49s", product->name);
    printf("输入新单价: ");
    scanf("%f", &product->price);
    printf("输入新库存: ");
    scanf("%d", &product->stock);
    
    printf("\n商品信息更新成功!\n");
}

// 删除商品
void delete_product(ProductList* list) {
    if (list->count == 0) {
        printf("\n库存为空,无法删除\n");
        return;
    }
    
    int id;
    printf("\n请输入要删除的商品ID: ");
    scanf("%d", &id);
    
    if (id < 1 || id > list->count) {
        printf("无效的商品ID\n");
        return;
    }
    
    // 将最后一个元素移到要删除的位置
    if (id < list->count) {
        list->data[id - 1] = list->data[list->count - 1];
    }
    
    // 减少内存空间
    Product* new_data = realloc(list->data, (list->count - 1) * sizeof(Product));
    if (list->count > 1 && !new_data) {
        printf("内存重新分配失败!\n");
        return;
    }
    
    list->data = new_data;
    list->count--;
    
    // 重新生成ID序列
    for (int i = 0; i < list->count; i++) {
        list->data[i].id = i + 1;
    }
    
    printf("\n商品删除成功!\n");
}

// 搜索商品
void search_product(ProductList* list) {
    if (list->count == 0) {
        printf("\n库存为空\n");
        return;
    }
    
    char keyword[50];
    printf("\n请输入商品名称或ID: ");
    scanf("%49s", keyword);
    
    int found = 0;
    printf("\n搜索结果:\n");
    printf("%5s %-20s %10s %6s\n", "ID", "名称", "单价", "库存");
    printf("------------------------------------------------\n");
    
    for (int i = 0; i < list->count; i++) {
        if (strstr(list->data[i].name, keyword) || 
            (atoi(keyword) > 0 && list->data[i].id == atoi(keyword))) {
            printf("%5d %-20s %10.2f %6d\n", 
                   list->data[i].id,
                   list->data[i].name,
                   list->data[i].price,
                   list->data[i].stock);
            found = 1;
        }
    }
    
    if (!found) {
        printf("未找到匹配的商品\n");
    }
}

// 保存到文件
void save_to_file(const char* filename, ProductList* list) {
    FILE* file = fopen(filename, "wb");
    if (!file) {
        printf("无法打开文件进行保存!\n");
        return;
    }
    
    // 写入商品数量
    fwrite(&list->count, sizeof(int), 1, file);
    
    // 写入所有商品数据
    for (int i = 0; i < list->count; i++) {
        fwrite(&list->data[i], sizeof(Product), 1, file);
    }
    
    fclose(file);
    printf("\n数据已保存到 %s\n", filename);
}

// 从文件加载
int load_from_file(const char* filename, ProductList* list) {
    FILE* file = fopen(filename, "rb");
    if (!file) {
        printf("文件不存在,将创建新文件\n");
        return 0;
    }
    
    // 读取商品数量
    int count;
    fread(&count, sizeof(int), 1, file);
    
    if (count <= 0) {
        fclose(file);
        return 0;
    }
    
    // 分配内存
    Product* new_data = malloc(count * sizeof(Product));
    if (!new_data) {
        printf("内存分配失败!\n");
        fclose(file);
        exit(EXIT_FAILURE);
    }
    
    // 读取商品数据
    for (int i = 0; i < count; i++) {
        fread(&new_data[i], sizeof(Product), 1, file);
    }
    
    fclose(file);
    
    // 更新列表
    if (list->data) {
        free(list->data);
    }
    
    list->data = new_data;
    list->count = count;
    
    printf("\n从 %s 加载了 %d 个商品\n", filename, count);
    return 1;
}

3. 文件操作实现 (fileio.c)

// fileio.c
#include "product.h"
#include <stdio.h>
#include <stdlib.h>

// 清屏函数(跨平台)
void clear_screen() {
    #ifdef _WIN32
    system("cls");
    #else
    system("clear");
    #endif
}

4. 主程序与用户界面 (main.c)

// main.c
#include <stdio.h>
#include <stdlib.h>
#include "product.h"

#define FILENAME "supermarket.dat"

void display_menu() {
    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("请选择操作: ");
}

int main() {
    ProductList inventory;
    init_products(&inventory);
    
    // 加载已有数据
    load_from_file(FILENAME, &inventory);
    
    int choice;
    while (1) {
        display_menu();
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                add_product(&inventory);
                break;
            case 2:
                display_products(&inventory);
                break;
            case 3:
                modify_product(&inventory);
                break;
            case 4:
                delete_product(&inventory);
                break;
            case 5:
                search_product(&inventory);
                break;
            case 6:
                save_to_file(FILENAME, &inventory);
                break;
            case 7:
                save_to_file(FILENAME, &inventory);
                free(inventory.data);
                printf("\n系统已退出,数据已保存\n");
                return 0;
            default:
                printf("无效选项,请重新输入\n");
        }
        
        // 清除输入缓冲区
        while (getchar() != '\n');
        printf("\n按回车键继续...");
        getchar();
        clear_screen();
    }
}

系统功能详解

1. 数据管理功能

  • 动态内存管理​:使用realloc()动态调整内存大小
  • 自动ID生成​:商品ID根据添加顺序自动生成
  • 输入验证​:限制输入长度,防止缓冲区溢出
  • 高效删除​:通过移动最后一个元素实现O(1)复杂度删除

2. 文件操作功能

  • 二进制存储​:使用二进制格式保存数据,效率更高
  • 数据恢复​:启动时自动加载上次保存的数据
  • 错误处理​:文件操作包含错误检查,防止数据损坏

3. 用户界面设计

  • 菜单驱动​:直观的菜单导航系统
  • 跨平台清屏​:兼容Windows/Linux/macOS系统
  • 操作确认​:关键操作后提供成功反馈

编译与使用指南

编译方法(GCC)

gcc -c product.c fileio.c
gcc main.c product.o fileio.o -o supermarket
./supermarket

使用说明

  1. 首次运行会自动创建数据文件
  2. 添加商品时只需输入名称、价格和库存
  3. 可通过ID或名称关键字搜索商品
  4. 修改库存时直接输入新数值即可
  5. 退出系统前务必选择"保存数据"选项

扩展与优化建议

1.增加销售功能​:

// 添加销售函数
void sell_product(ProductList* list, int id, int quantity) {
    if (id < 1 || id > list->count) return;
    if (list->data[id-1].stock < quantity) {
        printf("库存不足!\n");
        return;
    }
    list->data[id-1].stock -= quantity;
    printf("已售出 %d 件 %s\n", quantity, list->data[id-1].name);
}

2.​增加统计功能​:

// 库存统计
void inventory_stats(ProductList* list) {
    float total_value = 0;
    printf("\n库存统计:\n");
    for (int i = 0; i < list->count; i++) {
        float value = list->data[i].price * list->data[i].stock;
        printf("%s: 数量=%d, 总价值=%.2f\n", 
               list->data[i].name, list->data[i].stock, value);
        total_value += value;
    }
    printf("\n库存总价值: %.2f\n", total_value);
}

3.性能优化技巧​:

  • 使用哈希表加速搜索
  • 分批写入文件减少I/O操作
  • 添加内存缓存机制

这个超市管理系统实现了核心的商品管理功能,代码结构清晰,注释完整,适合学习和课程设计使用。通过动态内存管理和文件操作,系统可以高效地处理商品数据,为超市日常运营提供了便捷的管理工具

资源推荐:

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

C/C++教程

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

posted @ 2025-07-08 15:28  C语言实战大全  阅读(48)  评论(0)    收藏  举报