C语言程序求助:移除CSV空行与引号后输出内容杂乱
问题排查与修复方案
原代码的核心问题
- 内层循环错误插入换行符:你把
c_row2[new] = '\n'放在了遍历每个字符的循环里,这会导致每处理一个非引号字符就插入一次换行,直接把内容拆得支离破碎。 - 缺少字符串终止符:
c_row2没有添加\0结束标记,fputs会持续读取内存中的垃圾数据直到遇到随机的\0,这是内容杂乱的主要原因。 - 循环条件不严谨:
- 写死循环211次,无法适配文件实际行数,也没法跳过空行。
- 依赖
c_row1[c] != '\n'判断行尾,但fgets读取的最后一行可能没有\n,会触发数组越界访问,导致未定义行为。
- 未处理空行:原需求要移除末尾空行,但代码没有判断当前行是否为空,直接写入新文件。
- 未检查文件打开状态:如果
file.csv不存在或无法读取,fopen返回NULL,后续操作会直接崩溃。
修复后的完整代码
#include <stdio.h> #include <string.h> #define CHAR 1024 // 定义合理的缓冲区大小,避免溢出 int main() { // 打开输入文件并检查是否成功 FILE *dr = fopen("file.csv", "r"); if (dr == NULL) { perror("Failed to open input file"); return 1; } // 打开输出文件并检查是否成功 FILE *cl = fopen("clean_file.txt", "w"); if (cl == NULL) { perror("Failed to open output file"); fclose(dr); return 1; } char c_row1[CHAR]; char c_row2[CHAR]; // 逐行读取直到文件结束 while (fgets(c_row1, CHAR, dr) != NULL) { // 判断当前行是否为空(仅含换行、空格或制表符) int is_empty = 1; for (int i = 0; c_row1[i] != '\0'; i++) { if (c_row1[i] != '\n' && c_row1[i] != ' ' && c_row1[i] != '\t') { is_empty = 0; break; } } if (is_empty) continue; // 跳过空行 int new = 0; // 遍历行内所有字符,直到字符串结束符 for (int c = 0; c_row1[c] != '\0'; c++) { if (c_row1[c] == '"') continue; // 跳过引号 c_row2[new++] = c_row1[c]; // 防止缓冲区溢出,预留位置给终止符 if (new >= CHAR - 1) break; } c_row2[new] = '\0'; // 添加字符串终止符,确保fputs正常工作 fputs(c_row2, cl); } // 关闭文件,避免资源泄漏 fclose(dr); fclose(cl); return 0; }
修复关键点说明
- 文件安全检查:添加
fopen返回值判断,避免空指针操作导致崩溃。 - 空行过滤:通过判断行内是否有有效字符,实现移除空行的需求。
- 正确处理行尾:用
c_row1[c] != '\0'遍历字符,兼容最后一行无\n的情况,避免数组越界。 - 字符串终止符:处理完每行后给
c_row2添加\0,确保fputs只写入有效内容。 - 移除错误换行:直接保留原行的换行符,不再重复插入,保证内容格式整齐。
- 缓冲区保护:限制
new的最大值,防止数组溢出。
内容的提问来源于stack exchange,提问作者Jacob Mohamed
相关产品推荐
相关产品推荐

