Парсинг текстового файла
Я пытаюсь разобрать 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