C/C++

Приходится три раза вводить EOF (Ctrl+Z), что же не так?

FILE* cub;

int create_cub()
{
char c[10], m[10];
int s;
cub = fopen("cubes.dat", "w");
if (cub == NULL) return -1;
printf("\n Input:\n");
while ((scanf("%d %s %s", &s,c,m)) != EOF){
printf("%2d%-9.9s%-9.9s\n", s, c, m);
fprintf(cub, "%2d%-9.9s%-9.9s", s, c, m);
while (getchar() != '\n');
}
fclose(cub);
return 0;
}
Цитата из man scanf
On success, these functions return the number of input items success‐
fully matched and assigned; this can be fewer than provided for, or
even zero, in the event of an early matching failure.

The value EOF is returned if the end of input is reached before either
the first successful conversion or a matching failure occurs. EOF is
also returned if a read error occurs, in which case the error indicator
for the stream (see ferror(3)) is set, and errno is set to indicate the
error.
Использование scanf("%s") НЕДОПУСТИМО, так как означает возможность выполнения произвольного кода в системе от имени пользователя, который запустил процесс на выполнение. Ниже пример того, как сделать ввод при помощи scanf более вменяемым и даже относительно безопасным.
 #include  

int main( int argc, char* argv[] )
{
int s;
int rc;
char c[10];
char m[10];
printf("Пример ввода данных при помощи богомерзкой scanf:\n");
while( !feof(stdin) )
{
rc = scanf("%d %9s %9s", &s, c, m );
if( rc == 3 )
{
printf("s = %d, c = '%s' m = '%s'\n", s, c, m );
}
else
{
if( rc != EOF )
{
fprintf( stderr, "Ошибка ввода данных\n" );
}
break;
}
}
return 0;
}
Возвращаемый результат при нормальном ввода:
 Пример ввода данных при помощи богомерзкой scanf: 
1 hello world
s = 1, c = 'hello' m = 'world'
2 another line
s = 2, c = 'another' m = 'line'
Тут был введен EOF
А вот что будет, если ввести мусор:
 1. Hello World 
s = 1, c = '.' m = 'Hello'
Ошибка ввода данных
 1 Hello World 
s = 1, c = 'Hello' m = 'World'
2 Weeeeeeeeeeeeery long
s = 2, c = 'Weeeeeeee' m = 'eeeeery'
Ошибка ввода данных
Можно увидеть, что переполнения буфера не происходит.
Кончено лучше всего вообще не использовать богомерзкую scanf и производить ввод при помощи безопасной fgets
Ольга Абдульманова (Гордеева)
Ольга Абдульманова (Гордеева)
9 624
Лучший ответ
Василий Белаш СПАСИБО БОЛЬШОЕ!!!!!!!!!!!!!!!!
У вас в сканфе считывается три переменных, поэтому и нужно три EOF.
То что вы в stdin вводите символ конца файла не блокирует его. Поэтому остальные переменные будут ожидать ввода.
Просто сделайте три раздельных сканфа чтобы каждый считывал только одну переменную.
Гарик Дедян
Гарик Дедян
51 416

Похожие вопросы