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

如何使用C语言实现通用CSV文件列数统计功能?

适配任意分隔符的CSV行列统计实现方案

核心优化点

  • 移除固定的逗号分隔符硬编码,将分隔符改为可配置参数,支持手动指定
  • 可选增加自动分隔符检测逻辑:统计首行出现频次最高的非内容类特殊字符作为分隔符,适配无分隔符先验信息的场景
  • 可按需新增CSV标准兼容逻辑:双引号包裹的字段内部出现的分隔符不计入列统计,避免字段内容带分隔符时统计错误

修复优化后的代码

#include <stdio.h>
#include <ctype.h>

// 手动指定分隔符版本
int file_info(char delimiter){
    FILE *f;
    int countlines = 0;
    int countcols = 0;
    int c; // 必须用int存储getc返回值,否则EOF判断会出错
    int in_quote = 0; // 标记是否在双引号包裹的字段内,兼容标准CSV格式

    f = fopen("moradas.csv", "r");
    if (f == NULL) {
        printf("无法打开文件!");
        return 0;
    }

    for (c = getc(f); c != EOF; c = getc(f)){
        // 处理双引号转义
        if (c == '"') {
            in_quote = !in_quote;
        }
        // 统计行数
        if (c == '\n' && !in_quote) {
            countlines++;
        }
        // 仅统计首行非引号内的分隔符
        if (countlines == 0 && c == delimiter && !in_quote) {
            countcols++;
        }
    }

    // 处理文件最后一行没有换行符的情况
    if (c == EOF && countlines == 0 && countcols > 0) {
        countlines = 1;
    } else if (c == EOF && !feof(f)) {
        printf("文件读取错误!\n");
        fclose(f);
        return 0;
    }

    fclose(f);
    printf("行数: %d \n", countlines);
    printf("列数: %d \n", countcols + 1);
    return 0;
}

// 自动检测分隔符的辅助函数
char detect_delimiter() {
    FILE *f = fopen("moradas.csv", "r");
    if (f == NULL) return ','; // 检测失败默认用逗号
    int freq[256] = {0};
    int c;
    // 只统计首行的字符频次
    while ((c = getc(f)) != EOF && c != '\n') {
        // 排除内容类字符,只统计可能的分隔符
        if (!isalnum(c) && c != '"' && c != ' ' && c != '\'') {
            freq[c]++;
        }
    }
    fclose(f);
    // 找频次最高的字符作为分隔符
    char delimiter = ',';
    int max_freq = 0;
    for (int i = 0; i < 256; i++) {
        if (freq[i] > max_freq) {
            max_freq = freq[i];
            delimiter = (char)i;
        }
    }
    return delimiter;
}

int main(){
    int option;
    printf("选择功能\n1: 获取CSV文件信息\n2: 其他功能\n");
    scanf("%d", &option);
    switch(option) {
        case 1:
            // 两种使用方式二选一:
            // 1. 手动指定分隔符,比如分号就传';',制表符传'\t'
            // file_info(',');
            // 2. 自动检测分隔符
            char delimiter = detect_delimiter();
            printf("自动检测到的分隔符: '%c'\n", delimiter);
            file_info(delimiter);
            break;
        case 2:
            printf("2\n");
            break;
        default:
            printf("请选择有效选项!\n");
    }
    return 0;
}

注意事项

  • 如果明确知道待处理CSV的分隔符,直接调用file_info传入对应字符即可,无需使用自动检测逻辑,准确率更高
  • 代码新增了双引号字段兼容逻辑,符合RFC4180 CSV标准,避免字段内容带分隔符时统计出错
  • 修复了原代码中char c判断EOF出错、最后一行无换行符时行数统计不准的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 23:06:03