商场购物结算系统

项目名称: 商场购物结算系统

软件环境: Linux操作系统(或Visual Studio Code)

开发工具: GCC

硬件环境: 计算机

项目描述 :项目是基于 C 语言开发的一个商场购物结算系统。该系统模拟了用户在超市购物的整个流程,提供了商品购买、退货、更换以及查看等功能。同时,系统引入了会员管理机制,支持会员折扣和积分累积,可以积分换购商品。该系统可以提升购物结算的效率和用户体验。

技术实现

C 语言编程: 利用 C 语言的标准库函数(如 stdio.hstring.hstdlib.h)实现各项功能。
模块化设计: 将系统划分为 product, cart, member, menu, main 等模块,通过 .h 和 .c 文件组织代码,提高可读性和可维护性。
结构体应用: 使用 Product 和 Member 结构体来组织商品和会员数据。
数组管理: 利用静态数组管理购物车和会员信息。
字符串处理: 使用 strncpystrcspn 等函数处理商品和会员姓名等字符串信息。
函数调用与流程控制: 通过函数调用实现模块间的通信,使用 switch 语句和 do-while 循环控制程序流程。
会员折扣与积分: 在结账时,通过会员ID查找会员,应用折扣率并根据消费金额累积积分。

项目结构及源码:

product.h

#ifndef PRODUCT_H
#define PRODUCT_H

// 定义商品结构体
typedef struct {
    int productId;        // 产品编号
    char productName[50]; // 产品名称
    int quantity;         // 购买数量
    float unitPrice;      // 产品单价
    float totalPrice;     // 产品总计价格
} Product;

// 定义最大支持的商品项数(不同商品项的数量)
#define MAX_PRODUCTS 100

#endif // PRODUCT_H

cart.h

#ifndef CART_H
#define CART_H

#include "product.h"

// 初始化购物车
void initializeCart();

// 向购物车添加商品
void addProductToCart(int productId, const char* productName, int quantity, float unitPrice);

// 根据产品ID从购物车移除商品 (退货)
void removeProductFromCart(int productId);

// 更新购物车中商品的信息 (数量)
void updateProductInCart(int productId, int newQuantity);

// 查看购物车中的所有商品
void viewAllProductsInCart();

// 根据产品ID查看购物车中的特定商品信息
void viewProductByIdInCart(int productId);

// 结账,计算总价并清空购物车
// 添加一个参数来接收会员ID
float checkoutCart(int memberId); // 返回总金额

#endif // CART_H

cart.c

#include "cart.h"
#include <stdio.h>
#include <string.h>
#include "member.h" // 引入会员系统头文件

// 静态数组用于存储会员信息
static Product shoppingCart[MAX_PRODUCTS];
static int itemCount = 0; // 当前购物清单中的商品项数

// 初始化购物车
void initializeCart() {
    itemCount = 0;
    // printf("购物车已初始化。\n"); // 在主函数中统一打印欢迎信息
}

// 向购物车添加商品
void addProductToCart(int productId, const char* productName, int quantity, float unitPrice) {
    if (itemCount >= MAX_PRODUCTS) {
        printf("错误:购物车已满,无法添加更多商品。\n");
        return;
    }

    // 检查商品是否已存在,如果存在则更新数量,而不是重复添加
    for (int i = 0; i < itemCount; i++) {
        if (shoppingCart[i].productId == productId) {
            printf("商品 '%s' (ID: %d) 已存在。更新数量。\n", productName, productId);
            shoppingCart[i].quantity += quantity; // 直接增加数量
            shoppingCart[i].totalPrice = shoppingCart[i].quantity * shoppingCart[i].unitPrice;
            printf("商品 '%s' 的购买数量已更新为 %d。\n", shoppingCart[i].productName, shoppingCart[i].quantity);
            return;
        }
    }

    // 添加新商品
    shoppingCart[itemCount].productId = productId;
    strncpy(shoppingCart[itemCount].productName, productName, sizeof(shoppingCart[itemCount].productName) - 1);//最多拷贝shoppingCart[itemCount].productName) - 1字节
    shoppingCart[itemCount].productName[sizeof(shoppingCart[itemCount].productName) - 1] = '\0'; // 确保字符串以空字符结尾
    shoppingCart[itemCount].quantity = quantity;
    shoppingCart[itemCount].unitPrice = unitPrice;//单价
    shoppingCart[itemCount].totalPrice = quantity * unitPrice;

    itemCount++;
    printf("商品 '%s' (ID: %d) 已成功添加到购物车。\n", productName, productId);
}

// 根据产品ID从购物车移除商品 (退货)
void removeProductFromCart(int productId) {
    int foundIndex = -1;
    for (int i = 0; i < itemCount; i++) {
        if (shoppingCart[i].productId == productId) {
            foundIndex = i;
            break;
        }
    }

    if (foundIndex == -1) {
        printf("错误:未找到产品ID为 %d 的商品。\n", productId);
        return;
    }

    // 将后面的元素向前移动,覆盖被删除的元素
    //从找到的索引处开始,直到倒数第二个元素
    for (int i = foundIndex; i < itemCount - 1; i++) {
        shoppingCart[i] = shoppingCart[i + 1];//将后一个元素复制到当前位置
    }
    itemCount--;//商品数量减一
    printf("产品ID为 %d 的商品已从购物车中移除。\n", productId);
}

// 更新购物车中商品的信息 (例如:数量)
void updateProductInCart(int productId, int newQuantity) {
    int foundIndex = -1;// 初始化未找到的索引
    for (int i = 0; i < itemCount; i++) {
        if (shoppingCart[i].productId == productId) {
            foundIndex = i;
            break;
        }
    }

    if (foundIndex == -1) {
        printf("错误:未找到产品ID为 %d 的商品,无法更新。\n", productId);
        return;
    }

    if (newQuantity <= 0) {
        printf("警告:更新数量无效,商品 '%s' (ID: %d) 将被移除。\n", shoppingCart[foundIndex].productName, productId);
        removeProductFromCart(productId); // 如果数量为0或负数,视为移除
        return;
    }

    shoppingCart[foundIndex].quantity = newQuantity;
    shoppingCart[foundIndex].totalPrice = newQuantity * shoppingCart[foundIndex].unitPrice;
    printf("商品 '%s' (ID: %d) 的购买数量已更新为 %d。\n", shoppingCart[foundIndex].productName, productId, newQuantity);
}

// 查看购物车中的所有商品
void viewAllProductsInCart() {
    if (itemCount == 0) {
        printf("购物车为空。\n");
        return;
    }

    printf("\n--- 已购商品清单 ---\n");
    printf("ID\t名称\t\t数量\t单价\t总计\n");
    printf("--------------------------------------------------\n");
    for (int i = 0; i < itemCount; i++) {
        printf("%d\t%-10s\t%d\t%.2f\t%.2f\n",
               shoppingCart[i].productId,
               shoppingCart[i].productName,
               shoppingCart[i].quantity,
               shoppingCart[i].unitPrice,
               shoppingCart[i].totalPrice);
    }
    printf("--------------------------------------------------\n");
}

// 根据产品ID查看购物车中的特定商品信息
void viewProductByIdInCart(int productId) {
    int found = 0;// 标记是否找到商品
    for (int i = 0; i < itemCount; i++) {// 遍历购物车
        if (shoppingCart[i].productId == productId) {
            printf("\n--- 商品信息 (ID: %d) ---\n", productId);
            printf("名称: %s\n", shoppingCart[i].productName);
            printf("购买数量: %d\n", shoppingCart[i].quantity);
            printf("产品单价: %.2f\n", shoppingCart[i].unitPrice);
            printf("产品总计价格: %.2f\n", shoppingCart[i].totalPrice);
            printf("------------------------\n");
            found = 1;
            break; // 找到后就可以退出循环了
        }
    }

    if (!found) {// 如果循环结束仍未找到
        printf("错误:未找到产品ID为 %d 的商品。\n", productId);
    }
}

// 结账,计算总价并清空购物车
// 修改为接收会员ID并应用折扣和积分
float checkoutCart(int memberId) {
    if (itemCount == 0) {// 如果购物车为空
        printf("购物车为空,无需结账。\n");
        return 0.0; // 返回0表示没有金额
    }

    float totalBillBeforeDiscount = 0.0;// 存储折扣前的总金额
    printf("\n--- 结账清单 ---\n");
    printf("ID\t名称\t\t数量\t单价\t总计\n");
    printf("--------------------------------------------------\n");
    for (int i = 0; i < itemCount; i++) {
        printf("%d\t%-10s\t%d\t%.2f\t%.2f\n",
               shoppingCart[i].productId,
               shoppingCart[i].productName,
               shoppingCart[i].quantity,
               shoppingCart[i].unitPrice,
               shoppingCart[i].totalPrice);
        totalBillBeforeDiscount += shoppingCart[i].totalPrice;// 累加总金额
    }
    printf("--------------------------------------------------\n");

    float finalAmount = totalBillBeforeDiscount;// 初始化最终金额为折扣前总金额
    int pointsEarned = 0;//积分奖励初始化为0

    // 查找会员并应用折扣
    Member* currentMember = findMemberById(memberId);//// 调用会员模块查找会员
    if (currentMember != NULL) {//找到会员
        printf("会员折扣 (%.0f%%): %.2f\n", (1.0f - currentMember->discountRate) * 100.0f, totalBillBeforeDiscount * (1.0f - currentMember->discountRate));
        finalAmount *= currentMember->discountRate; // 应用折扣,更新最终金额

        // 计算积分奖励:每满10元奖励1积分
        pointsEarned = (int)(totalBillBeforeDiscount / 10.0f); // 使用原价计算积分
        if (pointsEarned > 0) {
            addPointsToMember(memberId, pointsEarned);
        }
    } else {
        // 非会员或会员ID无效,不应用折扣和积分
        printf("非会员或会员ID无效,无折扣和积分奖励。\n");
    }

    printf("最终应付金额: %.2f\n", finalAmount);
    printf("感谢您的购物!祝您生活愉快。\n");

    // 清空购物车
    itemCount = 0;
    return finalAmount; // 返回最终支付金额
}

member.h

#ifndef MEMBER_H
#define MEMBER_H

// 定义会员结构体
typedef struct {
    int memberId;           // 会员编号
    char memberName[50];    // 会员姓名
    float discountRate;     // 折扣率 (例如 0.8 表示8折)
    int points;             // 会员积分
} Member;

// 定义最大会员数量
#define MAX_MEMBERS 50

// --- 会员操作函数声明 ---

// 初始化会员系统
void initializeMemberSystem();

// 添加新会员
void addMember(int memberId, const char* memberName, float discountRate);

// 根据会员ID查找会员
//返回一个指向 Member 结构体的指针,找到会员,通过这个指针直接修改会员对象
Member* findMemberById(int memberId);

// 增加会员积分
void addPointsToMember(int memberId, int pointsToAdd);


// 显示会员信息 (可选)
void displayMemberInfo(int memberId);

#endif // MEMBER_H

member.c

#include "member.h"
#include <stdio.h>
#include <string.h>

// 静态数组用于存储会员信息
static Member members[MAX_MEMBERS];
static int memberCount = 0;

// 初始化会员系统
void initializeMemberSystem() {
    memberCount = 0;
    // 可以在这里预先添加一些示例会员
    printf("会员系统已初始化。\n");
}

// 添加新会员
void addMember(int memberId, const char* memberName, float discountRate) {
    if (memberCount >= MAX_MEMBERS) {
        printf("错误:会员数量已满,无法添加更多会员。\n");
        return;
    }

    // 检查会员ID是否已存在
    if (findMemberById(memberId) != NULL) {
        printf("错误:会员ID %d 已存在。\n", memberId);
        return;
    }

    members[memberCount].memberId = memberId;
    strncpy(members[memberCount].memberName, memberName, sizeof(members[memberCount].memberName) - 1);
    members[memberCount].memberName[sizeof(members[memberCount].memberName) - 1] = '\0';
    // 确保折扣率在有效范围内 (例如 0.5 到 1.0)
    if (discountRate >= 0.5f && discountRate <= 1.0f) {
        members[memberCount].discountRate = discountRate;
    } else {
        printf("警告:无效的折扣率 %.2f,默认为 1.0 (无折扣)。\n", discountRate);
        members[memberCount].discountRate = 1.0f;
    }
    members[memberCount].points = 0; // 新会员积分初始为0

    memberCount++;
    printf("新会员 '%s' (ID: %d) 添加成功。\n", memberName, memberId);
}

// 根据会员ID查找会员
Member* findMemberById(int memberId) {
    for (int i = 0; i < memberCount; i++) {
        if (members[i].memberId == memberId) {
            return &members[i]; // 返回指向找到的会员的指针
        }
    }
    return NULL; // 未找到,返回NULL
}

// 增加会员积分
void addPointsToMember(int memberId, int pointsToAdd) {
    Member* member = findMemberById(memberId);
    if (member != NULL) {
        if (pointsToAdd > 0) {
            member->points += pointsToAdd;
            printf("会员 %s (ID: %d) 获得了 %d 积分。当前积分: %d\n", member->memberName, memberId, pointsToAdd, member->points);
        }
    } else {
        printf("警告:无法为不存在的会员ID %d 增加积分。\n", memberId);
    }
}


// 显示会员信息 (可选函数)
void displayMemberInfo(int memberId) {
    Member* member = findMemberById(memberId);
    if (member != NULL) {
        printf("\n--- 会员信息 (ID: %d) ---\n", memberId);
        printf("姓名: %s\n", member->memberName);
        printf("折扣率: %.2f (%.0f%%)\n", member->discountRate, (1.0f - member->discountRate) * 100.0f);
        printf("当前积分: %d\n", member->points);
        printf("-------------------------\n");
    } else {
        printf("错误:未找到会员ID为 %d 的会员。\n", memberId);
    }
}

menu.h

#ifndef MENU_H
#define MENU_H

// 显示主菜单
void displayMainMenu();

// 处理用户选择并执行相应功能
// 这个函数需要能够处理会员相关的操作
void handleUserChoice();

// 内部函数声明
void handlePurchase();// 处理购买商品功能
void handleReturn();
void handleReplacement();
void handleView();
void handleCheckout();
// 新增会员相关处理函数
void handleMemberOptions(); // 处理会员菜单
void handleAddMember();     // 添加新会员
void handleViewMember();    // 查看会员信息

#endif // MENU_H

menu.c

#include "menu.h"
#include "cart.h" // 包含购物车模块的函数声明
#include "member.h" // 包含会员模块的函数声明
#include <stdio.h>
#include <string.h>

// 定义一个全局变量来存储当前激活的会员ID,如果是非会员则设为-1或0
// 也可以在每次结账时动态询问
static int currentMemberId = -1; // 初始状态为非会员

// 显示主菜单
void displayMainMenu() {
    printf("\n======== 商场购物结算系统 ========\n");
    printf("1. 购买商品\n");
    printf("2. 退货\n");
    printf("3. 更换商品\n");
    printf("4. 查看商品\n");
    printf("5. 结账\n");
    printf("6. 会员管理\n"); // 新增会员管理选项
    printf("0. 退出系统\n");
    printf("===================================\n");
    printf("请输入您的选择: ");
}

// 处理购买商品功能
void handlePurchase() {
    int id, quantity;
    char name[50];
    float price;

    printf("\n--- 购买商品 ---\n");
    printf("请输入产品编号: ");
    scanf("%d", &id);
    printf("请输入产品名称: ");
    
    // 清除输入缓冲区
    while (getchar() != '\n');
    fgets(name, sizeof(name), stdin);
    name[strcspn(name, "\n")] = 0; // 移除 fgets 读取的换行符

    printf("请输入购买数量: ");
    scanf("%d", &quantity);
    printf("请输入产品单价: ");
    scanf("%f", &price);

    // 输入验证
    if (quantity <= 0 || price < 0) {
        printf("错误:数量和单价必须是正数。\n");
        return;
    }

    addProductToCart(id, name, quantity, price);// 调用购物车模块的添加函数
}

// 处理退货功能
void handleReturn() {
    int id;
    printf("\n--- 退货 ---\n");
    printf("请输入要退货的产品编号: ");
    scanf("%d", &id);
    removeProductFromCart(id);// 调用购物车模块的移除函数
}

// 处理更换商品功能
void handleReplacement() {
    int id, newQuantity;
    printf("\n--- 更换商品 ---\n");
    printf("请输入要更换商品的产品编号: ");
    scanf("%d", &id);
    printf("请输入新的购买数量: ");
    scanf("%d", &newQuantity);
    updateProductInCart(id, newQuantity);// 调用购物车模块的更新函数
}

// 处理查看商品功能
void handleView() {
    int choice;
    int id;

    printf("\n--- 查看商品 ---\n");
    printf("1. 查看所有商品\n");
    printf("2. 查看特定商品信息\n");
    printf("请输入您的选择: ");
    scanf("%d", &choice);

    if (choice == 1) {
        viewAllProductsInCart(); // 调用购物车模块的显示所有商品函数
    } else if (choice == 2) {
        printf("请输入要查看的产品编号: ");
        scanf("%d", &id);
        viewProductByIdInCart(id); // 调用购物车模块的显示特定商品函数
    } else {
        printf("无效的查看选项。\n");
    }
}

// 处理结账功能
void handleCheckout() {
    printf("\n--- 结账 ---\n");
    int memberIdInput = -1; // 默认为非会员

    printf("您是会员吗?(输入会员ID,非会员请输入 -1): ");
    scanf("%d", &memberIdInput);

    if (memberIdInput != -1) {
        // 检查输入的会员ID是否存在
        if (findMemberById(memberIdInput) == NULL) {
            printf("警告:输入的会员ID无效,将按非会员处理。\n");
            memberIdInput = -1; // 重置为非会员
        }
    }
    
    // 调用购物车模块的结账函数,并将处理过的会员ID传递进去
    checkoutCart(memberIdInput);
    
    // 结账后,重置当前会员ID
    currentMemberId = -1; 
}

// 处理添加新会员
void handleAddMember() {
    int memberId;
    char name[50];
    float discountRate;

    printf("\n--- 添加新会员 ---\n");
    printf("请输入新的会员编号: ");
    scanf("%d", &memberId);
    printf("请输入会员姓名: ");
    while (getchar() != '\n'); // 清除缓冲区
    fgets(name, sizeof(name), stdin);
    name[strcspn(name, "\n")] = 0; // 移除换行符

    printf("请输入会员折扣率 (例如 0.8 表示8折, 1.0 表示无折扣): ");
    scanf("%f", &discountRate);

    addMember(memberId, name, discountRate);
}

// 处理查看会员信息
void handleViewMember() {
    int memberId;
    printf("\n--- 查看会员信息 ---\n");
    printf("请输入要查看的会员编号: ");
    scanf("%d", &memberId);
    displayMemberInfo(memberId);// 调用会员模块的显示信息函数
}

// 处理会员管理菜单
void handleMemberOptions() {
    int choice;
    while (1) { // 进入会员管理子菜单无限循环
        printf("\n--- 会员管理 ---\n");
        printf("1. 添加新会员\n");
        printf("2. 查看会员信息\n");
        printf("3. (暂不支持) 积分换购商品\n"); // 占位
        printf("0. 返回主菜单\n");
        printf("请输入您的选择: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                handleAddMember();
                break;
            case 2:
                handleViewMember();
                break;
            case 3:
                printf("积分换购功能尚未实现。\n");
                break;
            case 0:
                return; // 返回主菜单
            default:
                printf("无效的选择。\n");
        }
    }
}

main.c

#include <stdio.h>
#include "cart.h"   // 包含购物车模块的声明
#include "menu.h"   // 包含菜单模块的声明
#include "member.h" // 包含会员模块的声明

int main() {
    int choice = -1; // 初始化选择

    // 初始化系统
    initializeCart();// 初始化购物车
    initializeMemberSystem(); // 初始化会员系统
    printf("欢迎来到商场购物结算系统!\n");

    // 程序主循环
    do {
        displayMainMenu(); // 显示主菜单
        scanf("%d", &choice); // 获取用户选择

        switch (choice) {
            case 1:
                handlePurchase(); // 调用菜单模块的购买处理函数
                break;
            case 2:
                handleReturn();// 调用菜单模块的退货处理函数
                break;
            case 3:
                handleReplacement();// 调用菜单模块的更换商品处理函数
                break;
            case 4:
                handleView();// 调用菜单模块的查看商品处理函数
                break;
            case 5:
                handleCheckout(); //// 调用菜单模块的结账处理函数 (函数内部会处理会员ID)
                break;
            case 6:
                handleMemberOptions(); // 进入会员管理子菜单
                break;
            case 0:
                printf("感谢使用,系统退出。\n");
                break;
            default:
                printf("无效的选择,请重新输入。\n");
        }
    } while (choice != 0); // 当用户选择0时退出循环

    return 0;
}

项目中有具体注释,详细解释了该程序的实现代码

程序运行截图:

可以选择具体的操作。

项目的大致流程图:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值