【问题标题】:Reading a .CSV file in C [closed]在 C 中读取 .CSV 文件 [关闭]
【发布时间】:2014-09-24 07:54:20
【问题描述】:

我将在我的大学学习 C 一年的 Java,我们的第一个任务是读取 .CSV 文件中存在的值,但教科书不清楚,教授对我们帮助不大.这方面我真的没有太多方向,作业马上就要交了,所以我真的需要一些方向!

我想我可以自己完成大部分事情,但我只是不确定这段代码的作用......

static int extractItems(char *line, char row[][MAXLEN]) {
    char *item;
    int col = 0;
    for( ; ; ) {
        item = strtok(line, ",\r\n");
        if (item == NULL)
            break;
        if (col >= MAXCOLS) {
            tooWide = 1;
            break;
        }
        strncpy(row[col], item, MAXLEN);
        row[col][MAXLEN] = '\0'; // force null termination
        col++;
        line = NULL;  // required by strtok function
    }
    return col;
}

col指的是列号,第一个是0。

我知道它会检查线路中是否没有任何内容以及是否太宽,但其余的对我来说是陌生的。

【问题讨论】:

    标签: c csv


    【解决方案1】:

    我认为最好的解释方式是注释代码:

    static int extractItems(char *line, char row[][MAXLEN]) {
                                          //line is a char* to your array of chars
                                                         // - one long string
                                          //row is a two dimensional array of chars
                                                         // - an array of strings
        char *item;
        int col = 0;
        for( ; ; ) {                      //infinite loop, we can exit it with "break" though
            item = strtok(line, ",\r\n"); //string->token.  Returns a pointer to a string,
                                          //which is the next token in the input.
                                          //it does this by replacing the first character found 
                                          //from the second string passed (",\r\n") with '\0'
                                          //and returning the pointer to where it started 
                                          //searching from.
                                          //i.e. it cuts the string up into substings (tokens)
                                          //and returns a pointer to the next one each time 
                                          //it is called.
            if (item == NULL)             //if NULL we are at end of the line. so exit loop
                break;
            if (col >= MAXCOLS) {         //if we have read too much (reached our limit) then exit
                tooWide = 1;              //is this a global? anyway it is used to signal that there was too much data
                break;
            }
            strncpy(row[col], item, MAXLEN); //copy the temporary string returned by strtok to the array
            row[col][MAXLEN] = '\0';      // force null termination (C_string remember?)
            col++;                        // increment the number of words counted
            line = NULL;                  // required by strtok function
                                              //passing in NULL gets strtok to continue scanning
                                              //from the end of the previous successful scan
        }
        return col;
    }
    

    有关 strtok 的更多信息:this answer describes it well

    【讨论】:

      【解决方案2】:

      让我们打破程序并分析一下,

      static int extractItems(char *line, char row[][MAXLEN]) {
      

      line 是一个数组,其中包含从 CSV 文件中读取的当前行。
      row 是一个二维数组,其中每个项目都是 CSV 文件中的单个元素

       item = strtok(line, ",\r\n");
      

      strtok 函数将字符串,第一个参数,这里是line 分割成基于分隔符字符串的标记,第二个参数,这里是,\n\r 也就是说,如果 CSV 文件包含一行
      Hello, world 然后使用该行对 strtok 的后续调用,产生 Hello => 分割线, world => 在\n 处分割线,\r 在windows 中用作换行符
      For further reading refer this link

      现在各个元素在item 中获得,strncpy 复制 n,MAXLEN 个字符,将其复制到 row

      strncpy(row[col], item, MAXLEN); 
      row[col][MAXLEN] = '\0';
      

      然后用\0分隔

      col++;                       
      line = NULL;
      

      为下一个项目递增到下一个位置并将line 设置为 NILL 为下一个。

      由于数组row默认通过引用传递,一旦程序运行,row将包含CSV文件中的每个逗号分隔值。

      【讨论】: