fscanf (3) практически невозможно использовать, если вход строго не контролируется.Трудно отличить ошибки ввода-вывода от ошибок разбора.Вот почему гораздо чаще читать каждую строку с помощью fgets (3), а затем сканировать ее с помощью sscanf (3).
Поскольку sscanf возвращает количество проанализированных элементов, вы можете использовать это, чтобы определить, работает ли сканирование должным образом.Не нужно заглядывать во входные данные: если вы получили то, что ожидали, все готово, иначе попробуйте сканировать другим способом.Вот рабочий пример:
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
int
main( int argc, char *argv[] ) {
if( argc < 2 ) {
errx(EXIT_FAILURE, "syntax: %s filename", argv[0]);
}
FILE *input = fopen(argv[1], "r");
if( !input ) {
err(EXIT_FAILURE, "could not open '%s'", argv[0]);
}
static char line[128];
int n;
while( fgets(line, sizeof(line), input) != NULL ) {
double d1, d2;
int quantum;
if( 2 == sscanf(line, "%d(%lf)", &quantum, &d1) ) {
printf( "ok: %d\t%7.2f\n", 100 * quantum, d1 );
} else if( 2 == sscanf(line, "(%lf %lf)", &d1, &d2) ) {
printf( "ok: %7.2f\t%7.2f\n", d1, d2 );
} else {
printf( ">>> %s\n", line );
}
}
if( !feof(input) ) {
err(EXIT_FAILURE, "error reading %s", argv[1]);
}
return EXIT_SUCCESS;
}
Если вы обнаружите другие шаблоны, их легко добавить.Обратите внимание, что при сбое fgets программа возвращает успех, только если мы достигли конца файла.