#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_BARCODE_LENGTH 20
#define MAX_NAME_LENGTH 50
#define MAX_MANUFACTURER_LENGTH 50
#define N 100 // 定义最大商品数量
char barcodes[N][20];
#define FILENAME "products.txt"
// 定义日期结构体
struct Date{
int year;
int month;
int day;
};
// 定义保质期结构体
struct ShelfLife {
int months; // 保质期以月数表示
};
// 定义商品结构体
struct Product {
char barcode[20]; // 商品条形码
char name[50]; // 商品名称
float price; // 定价
int stock; // 库存数量
struct Date productionDate; // 生产日期
struct ShelfLife shelfLife; // 保质期
char manufacturer[50]; // 生产厂家
};
// 输入模块(带查重功能)
void input_product()
{
FILE* p1;
struct Product s[N];
int i, n = 0, repeat;
char barcode[20];
char ans = 'y';
p1 = fopen(FILENAME, "r");
if (p1 == NULL)
{
perror("fopen");
return;
}
while (fread(&s[n], sizeof(struct Product), 1, p1) == 1)
n++;
fclose(p1);
//p1 = fopen(FILENAME, "a");
while (ans == 'y' || ans == 'Y')
{
repeat = 0;
printf("商品条形码: ");
scanf("%s", barcode);
for (i = 0; i < n; i++)
if (strcmp(s[i].barcode, barcode) == 0)
{
printf("您输入的商品条形码已存在,请核实后重新输入......\n");
getchar();
repeat = 1;
break;
}
if (repeat) continue;
strcpy(s[n].barcode, barcode);
printf("商品名称: ");
scanf("%s", s[n].name);
printf("定价: ");
scanf("%f", &s[n].price);
printf("库存数量: ");
scanf("%d", &s[n].stock);
printf("生产日期(年 月 日): ");
scanf("%d %d %d", &s[n].productionDate.year, &s[n].productionDate.month, &s[n].productionDate.day);
printf("保质期(月数): ");
scanf("%d", &s[n].shelfLife.months);
printf("生产厂家: ");
scanf("%s", s[n].manufacturer);
// fwrite(&s[n], sizeof(struct Product), 1, p1);
n++;
getchar();
printf("继续输入吗?(y/n)");
scanf("%c", &ans);
}
p1 = fopen(FILENAME, "w");
fwrite(s, sizeof(struct Product), n, p1);
fclose(p1);
}
// 浏览模块
void browse_product()
{
FILE* p1;
struct Product s;
int isDisplayed[N] = { 0 }; // 用于标记商品是否已显示,初始化为0表示都未显示
int productIndex = 0; // 记录商品的索引
p1 = fopen(FILENAME, "r");
if (p1 == NULL)
{
printf("文件打开失败!\n");
return;
}
printf("=======================================================================================================================================\n");
printf("%-20s\t%-20s\t%-10s\t%-10s\t%-15s\t%-10s\t%-30s\n",
"商品条形码", "商品名称", "定价(元)", "库存数量", "生产日期", "保质期(月数)", "生产厂家");
while (fread(&s, sizeof(struct Product), 1, p1) == 1)
{
if (!isDisplayed[productIndex]) // 如果该商品还未显示
{
printf("%-20s\t%-20s\t%-10.2f\t%-10d\t%-4d-%02d-%02d\t%-10d\t%-30s\n",
s.barcode, s.name,
s.price, s.stock,
s.productionDate.year, s.productionDate.month, s.productionDate.day,
s.shelfLife.months, s.manufacturer);
isDisplayed[productIndex] = 1; // 标记为已显示
}
productIndex++;
}
fclose(p1);
}
void printHeader();
void printProductInfo(const struct Product* s);
// 打印表头函数
void printHeader() {
printf("------------------------------------------------------- 查询到的商品信息如下:\n");
printf("%-20s\t%-20s\t%-10s\t%-10s\t%-15s\t%-10s\t%s\n",
"商品条形码", "商品名称", "定价", "库存数量", "生产日期", "保质期", "生产厂家");
}
// 打印商品信息函数
void printProductInfo(const struct Product* s) {
printf("%-20s\t%-20s\t%-10.2f\t%-10d\t%-4d-%02d-%02d\t%-10d\t%s\n",
s->barcode, s->name,
s->price, s->stock,
s->productionDate.year, s->productionDate.month, s->productionDate.day,
s->shelfLife.months, s->manufacturer);
}
// 查询商品函数
void query_product() {
FILE* p1;
struct Product s;
int choice;
char search[50];
int flag = 1;
p1 = fopen(FILENAME, "r");
if (p1 == NULL) {
printf("文件打开失败!\n");
return;
}
int printed[N] = { 0 }; // 用于标记商品是否已打印
int foundFlag; // 将foundFlag变量定义移到switch语句外部
while (flag) {
printf("============================== 查询商品 ==============================\n");
printf("1. ======================== 根据商品条形码查询 ======================\n");
printf("2. ======================== 根据商品名称查询 ========================\n");
printf("3. ======================== 根据生产厂家查询 ========================\n");
printf("***************=========== 请选择查询方式(输入0退出查询): ");
// 增加输入合法性检查,处理非法字符等情况
while (scanf("%d", &choice) != 1) {
while (getchar() != '\n'); // 清空输入缓冲区
printf("输入无效,请输入一个整数: ");
}
if (choice == 0) {
flag = 0;
break;
}
foundFlag = 0; // 在每次进入switch语句前初始化foundFlag
switch (choice) {
case 1:
printf("请输入商品条形码: ");
scanf("%s", search);
while (fread(&s, sizeof(struct Product), 1, p1) == 1) {
if (strcmp(s.barcode, search) == 0) {
if (!foundFlag) {
printf("------------------------------------------------------- 查询到的商品信息如下:\n");
printf("%-20s\t%-20s\t%-10s\t%-10s\t%-15s\t%-10s\t%s\n",
"商品条形码", "商品名称", "定价", "库存数量", "生产日期", "保质期", "生产厂家");
foundFlag = 1;
}
printProductInfo(&s);
break;
}
}
if (!foundFlag) {
printf("未找到该条形码对应的商品\n");
}
rewind(p1);
break;
case 2:
printf("请输入商品名称: ");
scanf("%s", search);
while (fread(&s, sizeof(struct Product), 1, p1) == 1) {
if (strstr(s.name, search) != NULL) {
if (!foundFlag) {
printf("------------------------------------------------------- 查询到的商品信息如下:\n");
printf("%-20s\t%-20s\t%-10s\t%-10s\t%-15s\t%-10s\t%s\n",
"商品条形码", "商品名称", "定价", "库存数量", "生产日期", "保质期", "生产厂家");
foundFlag = 1;
}
printProductInfo(&s);
break;
}
}
if (!foundFlag) {
printf("未找到该名称对应的商品\n");
}
rewind(p1);
break;
case 3:
printf("请输入生产厂家: ");
scanf("%s", search);
int printedCount = 0;
while (fread(&s, sizeof(struct Product), 1, p1) == 1) {
if (strstr(s.manufacturer, search) != NULL) {
int alreadyPrinted = 0;
for (int i = 0; i < printedCount; i++) {
if (strcmp(s.barcode, barcodes[i]) == 0) {
alreadyPrinted = 1;
break;
}
}
if (!alreadyPrinted) {
if (!foundFlag) {
printf("------------------------------------------------------- 查询到的商品信息如下:\n");
printf("%-20s\t%-20s\t%-10s\t%-10s\t%-15s\t%-10s\t%s\n",
"商品条形码", "商品名称", "定价", "库存数量", "生产日期", "保质期", "生产厂家");
foundFlag = 1;
}
printProductInfo(&s);
if (printedCount < N) {
strcpy(barcodes[printedCount], s.barcode);
printedCount++;
}
}
}
}
if (!foundFlag) {
printf("未找到该生产厂家对应的商品\n");
}
rewind(p1);
break;
printf("无效选择,请重新输入\n");
}
}
fclose(p1);
}
// 从文件读取商品信息到数组
int readProductsFromFile(struct Product products[]) {
FILE* file = fopen(FILENAME, "r");
if (file == NULL) {
perror("无法打开文件");
return 0;
}
int count = 0;
while (count < N && fread(&products[count], sizeof(struct Product), 1, file) == 1) {
count++;
}
fclose(file);
return count;
}
// 将商品信息数组写回到文件
void writeProductsToFile(struct Product products[], int count) {
FILE* file = fopen(FILENAME, "w");
if (file == NULL) {
perror("无法打开文件");
return;
}
for (int i = 0; i < count; i++) {
fwrite(&products[i], sizeof(struct Product), 1, file);
}
fclose(file);
}
// 显示商品信息函数
void displayProduct(struct Product p) {
printf("条形码: %s\n", p.barcode);
printf("名称: %s\n", p.name);
printf("定价: %.2f\n", p.price);
printf("库存数量: %d\n", p.stock);
printf("生产日期: %d-%02d-%02d\n", p.productionDate.year, p.productionDate.month, p.productionDate.day);
printf("保质期: %d 个月\n", p.shelfLife.months);
printf("生产厂家: %s\n", p.manufacturer);
printf("----------------------------\n");
}
// 修改商品信息函数
void modify_product() {
int continueModify = 1;
struct Product products[N];
int productCount = readProductsFromFile(products);
while (continueModify) {
int choice;
char searchValue[MAX_BARCODE_LENGTH + MAX_NAME_LENGTH];
char confirm;
int foundIndex = -1;
printf("============================== 修改商品 ==============================\n");
printf("1. ======================== 根据商品条形码修改 ======================\n");
printf("2. ======================== 根据商品名称修改 ========================\n");
printf("请选择修改方式(输入0返回主菜单): ");
scanf("%d", &choice);
if (choice == 0) {
break;
}
switch (choice) {
case 1:
printf("请输入要修改商品的条形码: ");
scanf("%s", searchValue);
for (int i = 0; i < productCount; i++) {
if (strcmp(products[i].barcode, searchValue) == 0) {
foundIndex = i;
break;
}
}
break;
case 2:
printf("请输入要修改商品的名称: ");
scanf("%s", searchValue);
for (int i = 0; i < productCount; i++) {
if (strcmp(products[i].name, searchValue) == 0) {
foundIndex = i;
break;
}
}
break;
default:
printf("无效选择!请重新输入\n");
continue;
}
if (foundIndex != -1) {
printf("原来的商品信息如下:\n");
displayProduct(products[foundIndex]);
printf("是否要修改该商品信息?(y/n): ");
while (getchar() != '\n');
scanf("%c", &confirm);
if (confirm == 'y' || confirm == 'Y') {
printf("请输入新的商品条形码: ");
scanf("%s", products[foundIndex].barcode);
printf("请输入新的商品名称: ");
scanf("%s", products[foundIndex].name);
printf("请输入新的定价: ");
scanf("%f", &products[foundIndex].price);
printf("请输入新的库存数量: ");
scanf("%d", &products[foundIndex].stock);
printf("请输入新的生产日期(年 月 日): ");
scanf("%d %d %d", &products[foundIndex].productionDate.year, &products[foundIndex].productionDate.month, &products[foundIndex].productionDate.day);
printf("请输入新的保质期(月): ");
scanf("%d", &products[foundIndex].shelfLife.months);
printf("请输入新的生产厂家: ");
scanf("%s", products[foundIndex].manufacturer);
printf("修改后的商品信息如下:\n");
displayProduct(products[foundIndex]);
}
else {
printf("已取消修改。\n");
}
}
else {
printf("未找到该商品!\n");
}
printf("是否继续修改其他商品?(y/n): ");
while (getchar() != '\n');
scanf("%c", &confirm);
if (confirm != 'y' && confirm != 'Y') {
continueModify = 0;
}
}
// 当不再继续修改时,一次性将修改后的信息写回文件
writeProductsToFile(products, productCount);
printf("商品信息已成功修改并保存。\n");
}
// 删除模块
void delete_product() {
int continueDelete = 1;
struct Product products[N];
int productCount = readProductsFromFile(products);
int foundIndex;
while (continueDelete) {
int choice;
char searchValue[MAX_MANUFACTURER_LENGTH];
char confirm;
int foundIndices[N]; // 用于存储找到的商品索引
int foundCount = 0; // 记录找到的商品数量
printf("============================== 删除商品 ==============================\n");
printf("1. ======================== 根据商品条形码删除 ======================\n");
printf("2. ======================== 根据商品名称删除 ========================\n");
printf("3. ======================== 根据生产厂家删除 ======================\n");
printf("请选择删除方式(输入0返回主菜单): ");
scanf("%d", &choice);
if (choice == 0) {
break;
}
switch (choice) {
case 1:
printf("请输入要删除商品的条形码: ");
scanf("%s", searchValue);
for (int i = 0; i < productCount; i++) {
if (strcmp(products[i].barcode, searchValue) == 0) {
foundIndex = i;
foundIndices[0] = foundIndex;
foundCount = 1;
break;
}
}
break;
case 2:
printf("请输入要删除商品的名称: ");
scanf("%s", searchValue);
for (int i = 0; i < productCount; i++) {
if (strcmp(products[i].name, searchValue) == 0) {
foundIndex = i;
foundIndices[0] = foundIndex;
foundCount = 1;
break;
}
}
break;
case 3:
printf("请输入要删除商品的生产厂家: ");
scanf("%s", searchValue);
foundCount = 0;
for (int i = 0; i < productCount; i++) {
if (strcmp(products[i].manufacturer, searchValue) == 0) {
foundIndices[foundCount] = i;
foundCount++;
}
}
if (foundCount > 1) {
printf("找到多个来自该生产厂家的商品,选择要删除的商品:\n");
for (int i = 0; i < foundCount; i++) {
printf("%d. ", i + 1);
displayProduct(products[foundIndices[i]]);
}
int selectIndex;
printf("请输入要删除商品的编号: ");
scanf("%d", &selectIndex);
if (selectIndex >= 1 && selectIndex <= foundCount) {
foundIndex = foundIndices[selectIndex - 1];
}
else {
printf("无效的编号,已取消删除。\n");
continue;
}
}
else if (foundCount == 1) {
foundIndex = foundIndices[0];
}
else {
printf("未找到来自该生产厂家的商品!\n");
continue;
}
break;
default:
printf("无效选择!请重新输入\n");
continue;
}
if (foundCount > 0) {
printf("找到的商品信息如下:\n");
displayProduct(products[foundIndex]);
printf("是否要删除该商品信息?(y/n): ");
while (getchar() != '\n');
scanf("%c", &confirm);
if (confirm == 'y' || confirm == 'Y') {
// 将找到的商品从数组中移除(通过将后面的元素向前移动覆盖)
for (int i = foundIndex; i < productCount - 1; i++) {
products[i] = products[i + 1];
}
productCount--;
printf("商品已成功删除。\n");
}
else {
printf("已取消删除。\n");
}
}
printf("是否继续删除其他商品?(y/n): ");
while (getchar() != '\n');
scanf("%c", &confirm);
if (confirm != 'y' && confirm != 'Y') {
continueDelete = 0;
}
}
// 当不再继续删除时,一次性将修改后的信息写回文件
writeProductsToFile(products, productCount);
printf("商品信息已成功更新并保存。\n");
}
// 排序模块
void sort_product()
{
FILE* p1;
struct Product s[N], temp;
int n = 0, i, j;
int choice;
int flag = 1;
p1 = fopen(FILENAME, "r");
if (p1 == NULL)
{
printf("文件打开失败!\n");
return;
}
while (fread(&s[n], sizeof(struct Product), 1, p1) == 1)
n++;
fclose(p1);
while (flag) {
printf(" **********================================== 排序商品 ====================================*********\n");
printf("1. *****================================= 根据商品条形码排序 ==================================*****\n");
printf("2. *****================================= 根据库存数量排序 ===================================*****\n");
printf("3. *****================================= 根据生产日期排序 ===================================*****\n");
printf("4. *****================================= 根据保质期排序 ===================================*****\n");
printf(" 请选择排序方式: ");
scanf("%d", &choice);
if (choice == 0)
{
flag = 0;
break;
}
switch (choice)
{
case 1:
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
if (strcmp(s[i].barcode, s[j].barcode) > 0)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
printf("按商品条形码排序成功\n");
break;
case 2:
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
if (s[i].stock > s[j].stock)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
printf("按库存数量排序成功\n");
break;
case 3:
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
if (s[i].productionDate.year > s[j].productionDate.year)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
else if (s[i].productionDate.year == s[j].productionDate.year &&
s[i].productionDate.month > s[j].productionDate.month)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
else if (s[i].productionDate.year == s[j].productionDate.year &&
s[i].productionDate.month == s[j].productionDate.month &&
s[i].productionDate.day > s[j].productionDate.day)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
printf("按生产日期排序成功\n");
break;
case 4:
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
if (s[i].shelfLife.months > s[j].shelfLife.months)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
printf("按保质期排序成功\n");
break;
default:
printf("无效选择\n");
return;
}
p1 = fopen(FILENAME, "w");
if (p1 == NULL)
{
printf("文件打开失败,无法写入排序后内容!\n");
return;
}
for (i = 0; i < n; i++)
{
fwrite(&s[i], sizeof(struct Product), 1, p1);
}
fclose(p1);
// 显示排好序的商品信息
p1 = fopen(FILENAME, "r");
if (p1 == NULL) {
printf("文件打开失败,无法显示排序后内容!\n");
return;
}
printf("%-20s\t%-20s\t%-10s\t%-10s\t%-15s\t%-10s\t%s\n",
"商品条形码", "商品名称", "定价", "库存数量", "生产日期", "保质期", "生产厂家");
while (fread(&s[0], sizeof(struct Product), 1, p1) == 1)
{
printf("%-20s\t%-20s\t%-10.2f\t%-10d\t%-4d-%02d-%02d\t%-10d\t%s\n",
s[0].barcode, s[0].name,
s[0].price, s[0].stock,
s[0].productionDate.year, s[0].productionDate.month, s[0].productionDate.day,
s[0].shelfLife.months, s[0].manufacturer);
}
rewind(p1);
}
fclose(p1);
}
// 统计模块
void statistics_product()
{
FILE* p1;
struct Product s;
int count = 0;
int totalStock = 0;
float totalPrice = 0.0;
int lowStockCount = 0;
int threshold;
p1 = fopen(FILENAME, "r");
if (p1 == NULL)
{
printf("文件打开失败!\n");
return;
}
printf("请输入库存下限数值: ");
scanf("%d", &threshold);
while (fread(&s, sizeof(struct Product), 1, p1) == 1)
{
count++;
totalStock += s.stock;
totalPrice += s.price;
if (s.stock < threshold)
{
printf("库存低于下限的商品信息:\n ");
lowStockCount++;
printf("%-20s\t%-20s\t%-10s\t%-10s\t%-15s\t%-10s\t%s\n",
"商品条形码", "商品名称", "定价", "库存数量", "生产日期", "保质期", "生产厂家");
printf("%-20s\t%-20s\t%-10.2f\t%-10d\t%-4d-%02d-%02d\t%-10d\t%s\n",
s.barcode, s.name,
s.price, s.stock,
s.productionDate.year, s.productionDate.month, s.productionDate.day,
s.shelfLife.months, s.manufacturer);
}
}
fclose(p1);
if (count > 0)
{
printf("商品总数: %d\n", count);
printf("库存总量: %d\n", totalStock);
printf("商品总价: %.2f\n", totalPrice);
if (lowStockCount > 0)
{
printf("库存少于 %d 的商品有 %d 种,请及时进货。\n", threshold, lowStockCount);
}
}
else
{
printf("没有商品记录可供统计\n");
}
}
// 销售模块
void sell_product()
{
FILE* p1, * p2;
struct Product s;
char barcode[20];
int quantity;
int found = 0;
p1 = fopen(FILENAME, "r");
if (p1 == NULL)
{
printf("文件打开失败!\n");
return;
}
p2 = fopen("temp.txt", "w");
if (p2 == NULL)
{
printf("临时文件创建失败!\n");
fclose(p1);
return;
}
printf("请输入要销售商品的条形码: ");
scanf("%s", barcode);
printf("请输入销售数量: ");
scanf("%d", &quantity);
while (fread(&s, sizeof(struct Product), 1, p1) == 1)
{
if (strcmp(s.barcode, barcode) == 0)
{
found = 1;
if (s.stock >= quantity)
{
s.stock -= quantity;
printf("------------------------------------------------------- 销售成功或的商品信息如下:-----------------------------------------------------\n");
printf("%-20s\t%-20s\t%-10s\t%-10s\t%-15s\t%-10s\t%s\n",
"商品条形码", "商品名称", "定价", "库存数量", "生产日期", "保质期", "生产厂家");
printf("%-20s\t%-20s\t%-10.2f\t%-10d\t%-4d-%02d-%02d\t%-10d\t%s\n",
s.barcode, s.name,
s.price, s.stock,
s.productionDate.year, s.productionDate.month, s.productionDate.day,
s.shelfLife.months, s.manufacturer);
printf("销售成功,剩余库存: %d\n", s.stock);
}
else {
printf("库存不足,当前库存: %d\n", s.stock);
}
}
fwrite(&s, sizeof(struct Product), 1, p2);
}
if (!found)
{
printf("未找到该商品条形码\n");
}
fclose(p1);
fclose(p2);
remove(FILENAME);
rename("temp.txt",FILENAME);
}
int main()
{
int choice;
while (1)
{
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("9. **-------------------------------------- 退出系统 -------------------------------------**\n");
printf("请选择操作: ");
scanf("%d",&choice);
switch (choice)
{
case 1:
input_product();
break;
case 2:
browse_product();
break;
case 3:
query_product();
break;
case 4:
modify_product();
break;
case 5:
delete_product();
break;
case 6:
sort_product();
break;
case 7:
statistics_product();
break;
case 8:
sell_product();
break;
case 9:
printf("感谢使用,再见!\n");
return 0;
default:
printf("无效选择,请重新输入!\n");
}
}
return 0;
}
最新发布