C 中 strtok 后无法正确计算 CSV 中的元素

标签 c csv strtok fileparsing

在使用 strtok 用逗号和引号(双引号)分隔后,我有时只能看到正确的元素数量计数。通常 printf 的长度为 0,但有时也为 6 和 1,且代码无需更改。

我尝试过仅使用一个分隔符(逗号)并以不同的方式定义 strtok 的标记输出,并重新排列 while 循环中的语句顺序,其中行的其他元素被认为是分隔的。这些是我用来测试代码 (test.csv) 的 .csv 文件的几行。它与 NOAA 提供的 .csv 降水数据格式相同。

"STATION","NAME","DATE","PRCP","PRCP_ATTRIBUTES"
"US183459384","XYZ ABC 9.0 E, WA US","2019-01-06","0.65",",,N"
"US183459384","XYZ ABC 9.0 E, WA US","2019-01-12","0.46",",,N"
"US183459384","XYZ ABC 9.0 E, WA US","2019-01-13","0.09",",,N"
"US183459384","XYZ ABC 9.0 E, WA US","2019-01-14","0.01",",,N"
"US183459384","XYZ ABC 9.0 E, WA US","2019-01-15","0.60",",,N"
"US183459384","XYZ ABC 9.0 E, WA US","2019-01-16","1.93",",,N"

我的代码尝试如下。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 1024

int get_row(FILE *file, int row_num, char delim[]) {
    int n_line = 0;
    int field = 0;
    char row[BUFFER_SIZE], *line[BUFFER_SIZE];

    while (fgets(row, BUFFER_SIZE, file)) {
        if (n_line == row_num) {
            printf("Length of line %d is %ld elements!\n", n_line, strlen(row));
            char* element = strtok(row, delim);
            while (element != NULL) {
                printf("%s\n", element);
                line[field++] = strdup(element);
                element = strtok(NULL, delim);
            }
            return 0;
        } else {
          n_line++;
    }
    printf("There is no row %d in the file you selected.\n", row_num);
    return 0;
}

int main(int argc, char **argv) {
    FILE *file;
    char delim[]  = ", \"";

    file = fopen(”test.csv”, "r");
    if (!file) {
        printf("Error: could not open %s\n", file_name);
        return -1;
    }
    printf("Reading file...\n");
    get_row(file, 0, delim);
    fclose(file);
    return 0;
}

我希望结果显示 5,但所有行的结果都是 0 或 1,偶尔会显示 6。

最佳答案

该程序不应编译,因为 file_name 未定义。 另外,在 getrow 函数内部,元素的数量不应等于字段,而不是缓冲区的长度。此外,逗号 delim 也不起作用,因为字段中有逗号。 以下代码适用于 test.csv 文件中的给定行

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 1024

int get_row(FILE *file, int row_num, char delim[]) {
    int n_line = 0;
    int field = 0;
    char row[BUFFER_SIZE], *line[BUFFER_SIZE];

    while (fgets(row, BUFFER_SIZE, file)) {
        if (n_line == row_num) {
            char* element = strtok(row, delim);
            while (element != NULL) {
                if(strcmp(",", element) != 0 &&  strcmp("\n", element) != 0)
                {
                  printf("%s\n", element);
                  line[field++] = strdup(element);
                }
                element = strtok(NULL, delim);
            }
            printf("Length of line %d is %d elements!\n", n_line, field);
            return 0;
        } else {
          n_line++;
    }
  }
    printf("There is no row %d in the file you selected.\n", row_num);
    return 0;
}

int main(int argc, char **argv) {
    FILE *file;
    char delim[]  = "\"";
    char file_name[] = "test.csv";

    file = fopen(file_name, "r");
    if (!file) {
        printf("Error: could not open %s\n", file_name);
        return -1;
    }
    printf("Reading file...\n");
    get_row(file, 0, delim);
    fclose(file);
    return 0;
}

关于C 中 strtok 后无法正确计算 CSV 中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56831823/

相关文章:

arrays - awk 输出元素乱序

objective-c - iOS 导出的 CSV 中的货币符号在 Excel 中无法正确显示

java - 在java中读取CSV文件时无法打印空行

c - 我认为的strtok问题

c - 使用 RubyFFI 从 ruby​​ 停止具有无限循环的 c 函数

C - 获取字符串前 n 个字符后的子字符串

c - 使用strtok分隔单词并删除, and ()

c++ - strcpy 可以在 Arduino 上编辑内存地址吗?

c++ - 如何将 libusb 与 libevent 一起使用?

c - 使用指针不会改变输出结构