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

C语言读取向量文件时strcat向字符串插入垃圾字符如何解决?

问题根源排查

你的代码存在4个核心问题,其中直接导致垃圾字符的是第2个:

    1. 第一次遍历完文件统计行数和逗号总数后,文件指针已经指向文件末尾,第二次循环调用getc会直接返回EOF,读取逻辑根本不会执行,你观察到的垃圾值本质是calloc初始化后未被覆盖的残留值,或者非法操作写入的乱码。
    1. 直接产生垃圾字符的核心错误:strcat要求传入的两个参数都是以\0结尾的合法C字符串,你传入的&c是单个字符的地址,后面没有自动追加\0,strcat拼接时会从&c地址往后读取内存,直到碰到随机的\0才停止,自然会混入大量垃圾字符。
    1. 变量重复定义:str、ret、X三个变量在代码中被重复声明两次,部分编译器会直接报错。
    1. 数组分配大小错误:你给X分配的大小是n*n,但实际你存储的是n行dim列的向量,应该分配n * dim * sizeof(double)的空间。

修复方案

按以下步骤修改代码即可解决问题:

  1. 第一次遍历统计完成后,调用rewind(file)将文件指针重置到文件开头。
  2. 不要用strcat拼接单个字符,改用下标直接赋值的方式往字符串里加字符,每次加完手动追加\0保证字符串合法。
  3. 删除重复的变量声明,修正数组分配的大小。
  4. 补充文件关闭、内存释放的逻辑,避免资源泄漏。

修复后可运行的核心代码示例

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

int main(int argc, char* argv[]) {
    FILE *file;
    int n = 1, dim, i=0;
    int c;
    int com=0;
    assert(argc==2 && "argc != 2");
    file = fopen(argv[1], "r");
    assert(file && "file open failed");
    
    // 第一遍统计行数和逗号数
    for(c = getc(file); c!= EOF; c = getc(file)){
        if(c == '\n'){
            n++;
        }
        else if(c==','){
            com++;
        }
    }
    dim = com/n +1;

    // 重置文件指针到开头
    rewind(file);

    double* X = (double *)calloc(n * dim, sizeof(double));
    assert(X); 
    char* str = (char *)calloc(100, sizeof(char));
    assert(str); 
    int str_pos = 0; // 记录当前字符串填充位置

    for(c = getc(file); c!= EOF; c = getc(file)){
        if(c!=',' && c!= '\n' && str_pos < 99){
            // 直接用下标赋值,不要用strcat
            str[str_pos++] = c;
            str[str_pos] = '\0'; // 手动加结束符
        }
        else{
            // 跳过空行的情况
            if (str_pos > 0) {
                double ret = strtod(str, NULL);
                X[i] = ret;
                i++;
                // 重置字符串位置
                str_pos = 0;
                str[0] = '\0';
            }
        }
    }
    // 处理最后一行没有换行符的情况,避免漏掉最后一个元素
    if (str_pos > 0) {
        double ret = strtod(str, NULL);
        X[i] = ret;
        i++;
    }

    // 测试输出
    for (int j = 0; j < n; j++) {
        for (int k = 0; k < dim; k++) {
            printf("%lf ", X[j*dim +k]);
        }
        printf("\n");
    }

    // 资源释放
    fclose(file);
    free(X);
    free(str);
    return 0;
}

内容的提问来源于stack exchange,提问作者Kahalon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:42:01