【问题标题】:How to parse each column in a CSV file using C如何使用 C 解析 CSV 文件中的每一列
【发布时间】:2019-02-21 06:42:53
【问题描述】:

我正在尝试使用 C 来读取 CSV 文件,逐行迭代(直到 EOF),并用逗号分隔/分割每一行。然后我希望将每一列分成“bins”并根据类型将它们添加到一个结构(这里没有显示;我在帮助文件中定义它)。

例如,如果我有1,Bob,我想将1Bob 拆分为两个变量。这是我到目前为止所写的内容。

void readFile(char file[25]) {
    FILE *fp;
    char line[1000];

    fp = fopen(file, "r"))

    while(fgets(line, 1000, fp)) {
        char* tmp = strdup(line);
        char* token;

        while((token = strsep(&tmp, ","))) {
            printf("%s\n", token);  // I want to split token[0] and token[1]
        }
    }
    fclose(fp);
}

上面的代码确实可以编译和运行。我只是不知道如何访问token 的每个拆分,例如token[0]token[1]。在 python 中,这很简单。对于每个line,我可以使用token[0]Bob 使用token[1] 访问1。但是在 C 中,我不能这样做。

出于测试目的,我现在所做的只是打印每一行(在第二个while 循环中),只是为了查看每个拆分的外观。我还没有实现将每个分割线放入其各自结构成员的代码。

我搜索了 Stack Overflow 并找到了大量关于此主题的主题。除了this one,他们似乎都没有帮助我,我从中汲取了。但我无法让拆分列的存储工作。

【问题讨论】:

  • 如果不出意外,您的代码中存在内存泄漏。不要忘记strdup 将您需要的内存分配给free
  • 我会调查strtok。我以前就是这样做的。
  • 还要注意strsep不是标准的C函数。而且您可能需要更仔细地阅读它的文档(如果您仍想使用它而不是标准的 C strtok 函数)。
  • 我将在我的代码中进行哪些更改以使其与strtok 一起使用?通过阅读一些文档,它看起来与strsep 的格式大致相同。我也可以得到第二块文本,还是一次只给出一个文本块(或令牌)?
  • 此外,没有法律或法令规定 CSV 行的长度必须少于 1000 个字符...如果您使用的是 POSIX,请考虑改用 getline!如果您复制每个字段或在那里解析它们,您可能不需要 strdup 行...

标签: c parsing


【解决方案1】:

在 python 中,这很简单。对于每个line,我可以使用token[0]Bob 使用token[1] 访问1。但是在 C 中,我不能这样做。

是的,你可以,只要你定义数组。

    while (fgets(line, sizeof line, fp))
    {
        char *tmp = strchr(line, '\n');
        if (tmp) *tmp = '\0';   // remove the '\n'
        tmp = strdup(line);
        #define MAXCOLUMNS  2
        char *token[MAXCOLUMNS];
        int c = 0;
        while (tmp)
        {
            if (c == MAXCOLUMNS) puts("too many columns"), exit(1);
            token[c++] = strsep(&tmp, ",");
        }
        if (1 <= c) printf("column 1: %s\n", token[0]);
        if (2 <= c) printf("column 2: %s\n", token[1]);
        // ONLY if the line's tokens are no longer needed:
        free(*token);
    }

【讨论】:

  • 这很有用,谢谢。但我不知道char *token[MAXCOLUMNS] 做了什么。看起来您正在定义一个长度为 MAXCOLUMNS 的新字符数组 token。但是你为什么使用*char token[MAXCOLUMNS] 不会做同样的事情吗?
  • @WaterGuy - char *token[MAXCOLUMNS](使用 MAXCOLUMNS 2)声明了一个由 2 个指向 char 的指针组成的数组,即。 e.指针数组,而不是字符数组。这些指针中的第一个 token[0] 稍后设置为 (strdup-licated) 行和第一列的开头,而这些指针中的第二个 token[1] 设置为第二列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
  • 2018-07-20
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
相关资源
最近更新 更多