如何使用fgets()从CSV文件读取值而不跳过数据?

时间:2019-03-31 21:34:08

标签: c csv fopen strtok getc

我正在尝试读取一个CSV文件,其中只有两个用逗号分隔的值。我正在使用char *fgets(char *str, int n, FILE *stream)函数来读取行。在代码中,要完成do-while循环,我正在使用getc()方法读取下一个字符,以了解是否已读取文件的末尾。问题是,getc()方法从下一行读取第一个字符,因此我正在丢失数据(因为下一行的第一个数字丢失一位)。如您所见,除了第一行之外,所有第一列条目都丢失了其第一个字符。

我应该使用什么来控制我的while循环?还是我应该使用另一种方法从CSV文件读取数据?非常感谢

my_file.csv中的数据:

3.0000,4.0000,5.0000,6.0000,7.0000
6.0000,5.0000,4.0000,3.0000,2.0000
9.0000,6.0000,3.0000,0.0000,-3.0000
12.0000,7.0000,2.0000,-3.0000,-8.0000
15.0000,8.0000,1.0000,-6.0000,-13.0000
18.0000,9.0000,0.0000,-9.0000,-18.0000

实际输出:

[在此处输入图片描述] [1]

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

void getData(char *buff);

int main() {

    char folder_addr[] = "C:\\my_file.csv";

    FILE *fp = fopen(folder_addr, "r");
    do  {
        char buff[1024];
        fgets(buff, 1024, (FILE*)fp);
        printf(buff);
        getData(buff);
    } while ((getc(fp)) != EOF);

    return 0;
};

void getData(char *buff){
    char *token = strtok(buff, ",");
    //printf("First value:  %s\n", token);

    while (token != NULL)   {
        //printf("First value:  %s\n", token);
        token = strtok(NULL, ",");
    }
}


  [1]: https://i.stack.imgur.com/fQzw1.jpg

2 个答案:

答案 0 :(得分:2)

do {fgets()...} while(getc);替换为while (fgets()) {...}

答案 1 :(得分:0)

最好的做法是仅执行while(fgets())而不是执行一段时间。我不会说偷看一个字符是最好的方法。

对于那些这样做是合理的选择(如果存在这种情况)的情况,可以执行fseek(fp, -1, SEEK_CUR)返回上一步。这有点难看,但还不错,可以完成工作。您需要像这样重新排序:

while ((getc(fp)) != EOF) {
    fseek(fp, -1, SEEK_CUR);
    char buff[1024];
    fgets(buff, 1024, (FILE*)fp);
    printf(buff);
    getData(buff);
} 

但是,请注意,fseek不能保证在流(例如管道)不可搜索时起作用。最好使用ungetc。相同的原则。您将刚刚读取的字符放回流中。

类似的方法是这样的:

int c;
while ((c = getc(fp)) != EOF) {
    char buff[1024];
    buff[0]=c;
    fgets(&buff[1], 1023, (FILE*)fp);
    printf(buff);
    getData(buff);
} 

您还应该将printf(buff)更改为puts(buff)