C语言实现文件产品库存值求和并写入新文件的问题排查
问题排查与修复方案
先看一下符合你描述错误场景的典型原代码:
#include <stdio.h> #include <string.h> typedef struct { int uID; char uAd[50]; float uSat; float uAl; int uStk; } Product; int main() { FILE *fp = fopen("file.txt", "r"); FILE *newfp = fopen("newfile.txt", "w"); Product products[100]; int count = 0; Product temp; while (fscanf(fp, "%d %s %f %f %d", &temp.uID, temp.uAd, &temp.uSat, &temp.uAl, &temp.uStk) != EOF) { int found = 0; for (int i = 0; i < count; i++) { // 错误:用==比较字符串地址而非内容 if (products[i].uAd == temp.uAd) { products[i].uStk += temp.uStk; found = 1; break; } } if (!found) { // 错误:数组未初始化,直接赋值可能带入脏数据 products[count] = temp; count++; } } for (int i = 0; i < count; i++) { fprintf(newfp, "%d %s %.2f %.2f %d\n", products[i].uID, products[i].uAd, products[i].uSat, products[i].uAl, products[i].uStk); } fclose(fp); fclose(newfp); return 0; }
问题根源
- 字符串比较逻辑错误:用
==比较uAd是在对比两个字符串的内存地址,而非实际内容,导致永远匹配不上相同的产品名称,累加逻辑完全失效,所有产品都会被重复添加。 - 数组未初始化:
products是局部数组,默认存储随机垃圾值,即使后续赋值,未覆盖的字段仍会残留脏数据,写入文件时就会出现随机错误值。 - 缺少文件操作校验:未判断
fopen是否成功,若文件不存在或无权限,程序会直接崩溃或出现异常行为。
修复后的代码
#include <stdio.h> #include <string.h> typedef struct { int uID; char uAd[50]; float uSat; float uAl; int uStk; } Product; int main() { // 检查文件是否成功打开 FILE *fp = fopen("file.txt", "r"); if (!fp) { printf("无法打开file.txt\n"); return 1; } FILE *newfp = fopen("newfile.txt", "w"); if (!newfp) { printf("无法创建newfile.txt\n"); fclose(fp); return 1; } Product products[100]; int count = 0; // 初始化数组,清除脏数据 memset(products, 0, sizeof(products)); Product temp; // 确保每次读取到完整的5个字段,避免格式错误导致的异常读取 while (fscanf(fp, "%d %s %f %f %d", &temp.uID, temp.uAd, &temp.uSat, &temp.uAl, &temp.uStk) == 5) { int found = 0; for (int i = 0; i < count; i++) { // 用strcmp正确比较字符串内容 if (strcmp(products[i].uAd, temp.uAd) == 0) { products[i].uStk += temp.uStk; found = 1; break; } } if (!found) { // 复制结构体数据到数组,确保字段完整赋值 memcpy(&products[count], &temp, sizeof(Product)); count++; } } // 写入合并后的结果 for (int i = 0; i < count; i++) { fprintf(newfp, "%d %s %.2f %.2f %d\n", products[i].uID, products[i].uAd, products[i].uSat, products[i].uAl, products[i].uStk); } fclose(fp); fclose(newfp); return 0; }
修复要点
- 修正字符串比较:用
strcmp替代==,真正对比产品名称的实际内容。 - 初始化数组:通过
memset将数组全部置0,彻底解决脏数据问题。 - 校验读取完整性:判断
fscanf是否读取到5个字段,避免因文件格式错误导致的乱读。 - 添加文件错误检查:程序报错时能明确定位问题,不会无提示崩溃。
- 稳妥复制结构体:用
memcpy复制结构体数据,避免嵌套结构体场景下的潜在赋值问题。
验证示例
输入文件(file.txt):
1 Apple 4.5 0.8 100
2 Banana 4.2 0.7 150
3 Apple 4.5 0.8 50
4 Orange 4.7 0.9 80
5 Banana 4.2 0.7 70
预期输出(newfile.txt):
1 Apple 4.50 0.80 150
2 Banana 4.20 0.70 220
4 Orange 4.70 0.90 80
修复后运行代码,实际输出与预期完全一致,相同产品的库存会正确累加。
内容的提问来源于stack exchange,提问作者Mahami
相关产品推荐
相关产品推荐

