Как читать значения из CSV-файла с помощью fgets (), не пропуская данные? - PullRequest
0 голосов
/ 01 апреля 2019

Я пытаюсь прочитать файл 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 ]

2 голосов
/ 01 апреля 2019

Замените ваш do {fgets()...} while(getc); на while (fgets()) {...}

0 голосов
/ 01 апреля 2019

Лучшее, что можно сделать, это просто сделать 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)

...