You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

修复要点

  1. 修正字符串比较:用strcmp替代==,真正对比产品名称的实际内容。
  2. 初始化数组:通过memset将数组全部置0,彻底解决脏数据问题。
  3. 校验读取完整性:判断fscanf是否读取到5个字段,避免因文件格式错误导致的乱读。
  4. 添加文件错误检查:程序报错时能明确定位问题,不会无提示崩溃。
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:50:25