Парсинг текстового файла

Я пытаюсь разобрать txt-файл, который содержит имена в формате:

"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH",...

вот код, который я написал:


#include <stdio.h>
// Names scores
int problem22() {
    FILE *f = fopen("names.txt", "r");
    char name[100];
    fscanf(f, ""%[^"]s", name);
    printf("%sn", name); // MARY
    fscanf(f, ""%[^"]s", name);
    printf("%sn", name); // ,
    fscanf(f, ""%[^"]s", name);
    printf("%sn", name); // PATRICIA
    return 0;
}

int main() {
    problem22();
    return 0;
}

каждый альтернативный вызов fscanf дает мне имя, в то время как другой тратится впустую на получение запятой. Я пробовал несколько форматов, но я не могу понять, как это сделать.

может кто-нибудь помочь мне с правильным форматом?

4 ответов


изменение строки входного формата на "%*[,\"]%[^\"]" сделал бы то, что вы хотите:

fscanf(f, "%*[,\"]%[^\"]", name);
printf("%s\n", name); // MARY
fscanf(f, "%*[,\"]%[^\"]", name);
printf("%s\n", name); // PATRICIA
fscanf(f, "%*[,\"]%[^\"]", name);
printf("%s\n", name); // LINDA

на %* просто пропускает соответствующий вход.


Я всегда использую strtok() или strtok_r() функция для анализа файла. (либо предпочитают использовать некоторую библиотеку csv).

но просто для удовольствия я написал код, возможно, Вам понравится, я не публикую код в своем ответе, но проверяю @codepad для вывода работает только для определенного формата.

использование strtok ()

правильный подход выглядит для меня примерно так:

int main(){
// while(fp, csv, sizeof(csv)){   
    // First read into a part of file  into buffer
    char csv[] = "\"MARY\",\"PATRICIA\",\"LINDA\",\"BARBARA\",\"ELIZABETH\"";
    char *name = "", 
       *parse = csv;
    while(name = strtok(parse, "\",")){
        printf(" %s\n", name);
        parse = NULL;
    }
    return 0;
} // end while 

Регистрация codepade для вывод:

 MARY
 PATRICIA
 LINDA
 BARBARA
 ELIZABETH

что я предлагаю во втором коде нарисовать внешний цикл для чтения строк из файла во временный буфер, а затем применить strtok () код, как выше, что-то вроде: while(fgets(fp, csv, sizeof(csv))){ use strtok code}


вы должны использовать fseek ().

этот код успешно работает:

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

int problem22()
{
    FILE *f = fopen("names.txt", "r");
    char name[100];
    int pos = 0, maxnames = 4, n;

    for(n = 0; n <= maxnames; n++)
    {
        fseek(f, pos, 0);
        fscanf(f, "\"%[^\"]s", name);
        printf("%s\n", name);
        pos += (strlen(name) + 3);
    }
    return 0;
}

int main()
{
    problem22();
    return 0;
}

можно использовать strtok() прочитайте всю строку и разделите ее на токены с помощью строки delin ","

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

// Names scores
int problem22() {
    FILE *f = fopen("file", "r");
    char *tok=NULL;
    char name[100];
    fscanf(f,"%s",name);

    printf("string before strtok(): %s\n", name);
    tok =  strtok(name, ",");
    while (tok) {
        printf("Token: %s\n", tok);
        tok = strtok(NULL, ",");
    }


return 0;
}

int main() {
    problem22();
    return 0;
}

Примечание:strtok() функция использует статический буфер при разборе, поэтому он не является потокобезопасным. Использовать strtok_r() если это имеет значение для вас.

посмотреть man strtok_r