项目名称: 商场购物结算系统
软件环境: Linux操作系统(或Visual Studio Code)
开发工具: GCC
硬件环境: 计算机
项目描述 :本项目是基于 C 语言开发的一个商场购物结算系统。该系统模拟了用户在超市购物的整个流程,提供了商品购买、退货、更换以及查看等功能。同时,系统引入了会员管理机制,支持会员折扣和积分累积,可以积分换购商品。该系统可以提升购物结算的效率和用户体验。
技术实现:
•C 语言编程: 利用 C 语言的标准库函数(如 stdio.h, string.h, stdlib.h)实现各项功能。
•模块化设计: 将系统划分为 product, cart, member, menu, main 等模块,通过 .h 和 .c 文件组织代码,提高可读性和可维护性。
•结构体应用: 使用 Product 和 Member 结构体来组织商品和会员数据。
•数组管理: 利用静态数组管理购物车和会员信息。
•字符串处理: 使用 strncpy, strcspn 等函数处理商品和会员姓名等字符串信息。
•函数调用与流程控制: 通过函数调用实现模块间的通信,使用 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;
}
项目中有具体注释,详细解释了该程序的实现代码
程序运行截图:

可以选择具体的操作。
项目的大致流程图:







