C语言CSV文件第二列匹配用户输入名称功能调试求助
问题分析与修复方案
代码中的核心问题
- 字符缓冲区定义错误:
char buffer;是单个字符变量,无法存储CSV的整行内容,fgets写入时会触发非法内存访问,导致未定义行为。必须改为字符数组char buffer[MAX_LINE];。 - 循环逻辑混乱:外层
while(token != NULL)完全多余,且第一次读取行后错误调用strtok(NULL, ";"),嵌套的while(fgets...)会跳过第一行数据,整体循环结构不符合逐行处理CSV的需求。 - 字符串比较方式错误:
bufferName == name比较的是两个指针的内存地址,而非字符串内容。C语言中必须用strcmp函数判断字符串相等,返回值为0时表示内容一致。 - 未处理空指针风险:如果某行CSV格式不完整(缺少第二列),
strtok(NULL, ";")会返回NULL,此时调用strcpy会触发空指针解引用,导致程序崩溃。
修复后的代码
// 假设MAX_LINE、bufferCode、bufferName已提前定义,且大小足够容纳对应字段 int count_name_duplicates(FILE *fp, const char *target_name) { int dupe = 0; char buffer[MAX_LINE]; // 修正:定义足够大的字符数组存储每行内容 // 逐行读取CSV文件 while (fgets(buffer, MAX_LINE, fp) != NULL) { // 提取第一列(代码字段) char *token = strtok(buffer, ";"); if (token == NULL) { continue; // 跳过格式错误的行 } strcpy(bufferCode, token); // 提取第二列(名称字段) token = strtok(NULL, ";"); if (token == NULL) { continue; // 跳过无第二列的行 } strcpy(bufferName, token); // 匹配目标名称并计数 if (strcmp(bufferName, target_name) == 0) { dupe++; } } return dupe; }
修复说明
- 缓冲区修正:将单个字符改为字符数组,确保能容纳CSV单行内容,避免内存越界。
- 循环逻辑简化:直接通过
while(fgets...)逐行读取,每行内用strtok依次分割字段,去除多余的外层循环。 - 正确字符串比较:用
strcmp替代指针地址比较,准确判断字符串内容是否匹配。 - 空指针防护:每次调用
strtok后检查返回值,跳过格式异常的行,避免程序崩溃。 - 函数封装:将逻辑封装为可复用函数,参数传入文件指针和目标名称,返回最终计数,结构更清晰。
内容的提问来源于stack exchange,提问作者hugo9152
相关产品推荐
相关产品推荐

