Вы должны проверить код возврата от fscanf()
; он сообщит вам, что преобразованы 2 значения вместо 3, которые вы ожидали. Вы всегда должны проверять код возврата из fscanf()
, обычно для ожидаемого количества преобразований, и только очень редко вы будете проверять EOF или 0.
Проблема в том, что набор сканирования %[^…]
не является модификатором для %s
, а также набор сканирования останавливается на первом ]
, если только он не следует сразу за [
для обычного набора сканирования или [^
для отрицательного набора сканирования. Итак, ваша строка формата ищет последовательность символов «не цифра или [
», за которой следуют ]
и s
- и она не находит ]
и s
во входных данных.
Тебе нужно:
#include <stdio.h>
int main(void)
{
const char *filename = "test.txt";
FILE *f = fopen(filename, "r");
if (f == 0)
{
fprintf(stderr, "Failed to open '%s' for reading\n", filename);
return 1;
}
int no,i;
char name[128];
if (fscanf(f, "%d %127[^0-9] %d", &no, name, &i) != 3)
{
fprintf(stderr, "Failed to read three values\n");
return 1;
}
printf("%d [%s] %d\n", no, name, i);
fclose(f);
return 0;
}
Вам нужно проверить, что fopen()
сработало. Сообщение об ошибке должно включать имя файла, который вам не удалось открыть. (Если вы обратили внимание на аргументы командной строки - используя int main(int argc, char **argv)
- вы также укажете имя программы из argv[0]
в сообщениях об ошибках.) Вам нужно выделить место для name
, а не использовать неинициализированный указатель. правильный тип возврата для main()
- int
, хотя Microsoft разрешает void
. Обратите внимание, что формат ввода гарантирует отсутствие переполнения буфера < / а>.
Я заключил имя в […]
в выводе, чтобы вы могли видеть, что имя включает конечный пробел. Результат, который я получаю:
24 [Rohit Soni ] 1997
person
Jonathan Leffler
schedule
17.12.2016
fgets
и каким-то другим способом разбирать строки на токены, чтобы вам больше никогда не пришлось использовать f / scanf. , потому что: Правило 4 о f / scanf: они действительно не годятся для многого. - person Steve Summit   schedule 18.12.2016