C语言实现CSV文件行列数统计的方法咨询
现有代码的基础问题修正
- 原有代码的换行判断存在逻辑错误:代码中写的是
chr == 'n',实际匹配的是字母n,而非换行符,应修改为chr == '\n',否则行数统计结果完全失效 - 缺少文件打开失败的校验:
fopen返回文件指针后需要判断是否为NULL,若文件不存在/无权限时直接读取会触发程序崩溃
CSV列数的正确统计实现逻辑
不能通过统计全文件的逗号总数推算列数。标准CSV格式中,被双引号包裹的字段内容本身可以包含逗号(例如 "张三,市场部"),这类逗号是字段内容的一部分,不属于列分隔符,直接全局计数会得到完全错误的结果。
正确的统计逻辑不需要数完全部逗号,仅需读取表头行的分隔符即可计算列数,核心判断规则如下:
- 逐字符遍历文件时维护
in_quote状态标记,初始值为0(代表不在双引号包裹的字段内部) - 遇到双引号
"时,直接翻转in_quote的状态值,双引号本身不参与分隔符判断 - 仅当
in_quote为0时,遇到的逗号,才是有效的列分隔符 - 单行内的列数 = 该行有效分隔符数量 + 1
- 遇到换行符时,完成当前行的分隔符计数后,重置分隔符计数与
in_quote状态,开始下一行的统计
整合后的可运行代码示例
#include <stdio.h> int main() { FILE *fileptr; int count_lines = 0; int col_sep_count = 0; int in_quote = 0; // 标记是否处于双引号包裹的字段内 char filechar[40], chr; printf("Enter file name: "); scanf("%s", filechar); fileptr = fopen(filechar, "r"); // 文件打开失败校验 if (fileptr == NULL) { printf("无法打开文件,请检查文件名或访问权限\n"); return 1; } chr = getc(fileptr); while (chr != EOF) { if (chr == '\n') { count_lines++; // 遇到换行时复位引号状态,防止格式异常残留影响后续计数 in_quote = 0; // 取第一行的分隔符数计算列数,读到第一行结束后不再更新列数结果 if (count_lines == 1) { int col_count = col_sep_count + 1; printf("CSV文件列数为: %d\n", col_count); } // 重置当前行的分隔符计数 col_sep_count = 0; } else { if (chr == '"') { in_quote = !in_quote; // 切换引号包裹状态 } else if (chr == ',' && in_quote == 0) { col_sep_count++; // 仅统计非引号包裹内的有效逗号 } } chr = getc(fileptr); } fclose(fileptr); printf("文件总行数为: %d\n", count_lines); return 0; }
实现注意事项
- 上述逻辑兼容标准CSV的引号包裹规则,不会把字段内容中的逗号误判为列分隔符
- 如果CSV文件不存在表头行,可根据需求调整判断分支,取任意有效行的分隔符数计算列数
- 遇到换行时强制复位引号状态,可兼容部分格式不标准的CSV文件(如引号未闭合的情况),避免统计逻辑被永久干扰
内容的提问来源于stack exchange,提问作者Prasad Tupe
相关产品推荐
相关产品推荐

