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

如何修复C程序Valgrind未初始化值警告并使用argv传参读取任意txt文件

问题1:Valgrind未初始化值警告修复

错误原因

  • 变量初始化错误:你写的int maxLength,maxLength1,maxLength2=0;仅给maxLength2赋值为0,maxLength和maxLength1都是未初始化的随机值,后续比较长度时读取了这两个未初始化变量,触发Valgrind警告。
  • 最大长度判断逻辑错误:你用else if串联三个判断,导致只要有一个条件满足,剩下两个字段的长度就不会被判断,无法正确统计三个字段各自的最大长度。

修复代码

修改readFile函数中的相关部分:

// 三个变量全部初始化为0
int maxLength = 0, maxLength1 = 0, maxLength2 = 0;
// ... 读取记录逻辑不变
// 去掉else if,三个判断独立执行
if(strlen(rec[i].description) > maxLength)
{
    maxLength = strlen(rec[i].description);
}
if(strlen(rec[i].octal) > maxLength1)
{
    maxLength1 = strlen(rec[i].octal);  
}
if(strlen(rec[i].define) > maxLength2)
{
    maxLength2 = strlen(rec[i].define);
}

问题2:通过argv传入任意文件名实现

修改步骤

  1. 给main函数增加命令行参数,接收用户输入的文件路径
  2. 增加参数合法性校验,提示用户正确用法
  3. 给readFile函数新增文件名入参,替换硬编码的固定文件名

修复代码

首先修改readFile的函数声明和定义:

// 新增filename参数接收传入的文件路径
void readFile(Record rec[], int *size,int *length, int *length1, int *length2, const char *filename)
{
    // 原有逻辑不变,仅把fopen的硬编码文件名替换为参数
    FILE *fp = fopen(filename, "r");
    // 后续原有逻辑不变
}

然后修改main函数:

int main(int argc, char *argv[])
{
    // 校验参数数量
    if(argc != 2)
    {
        printf("用法:%s <要读取的txt文件路径>\n", argv[0]);
        return 1;
    }
    Record recs[MAX_SIZE];
    int size = 0;
    int length=0;
    int length1=0;
    int length2=0;

    // 调用readFile时传入用户输入的文件路径
    readFile(recs, &size,&length,&length1,&length2, argv[1]);
     
    printTable(recs, size, length,length1,length2);

    return 0;
}

其他优化建议

  • define是C语言的预处理关键字,建议把结构体成员名改成define_str之类的命名,避免后续出现编译冲突。
  • 读取字符串时可以增加长度限制,比如fscanf(fp, "%19s %19s %19s\n", header1, header2, header3);,留一个字节存字符串结束符\0,避免缓冲区溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:48:02