Страница 1 из 1

Помогите со scanf() :(

Добавлено: 16 янв 2005, 18:29
Pasha
Здравствуйте! Пришло время когда в колледж на Computing надо написать coursework... Так как колледж под виндами, всё что есть из доступного - VB и VC -)

VB я, мягко говоря, не люблю, поэтому написал на C. Алгоритм работает, но есть одна проблема... (проявляется в С на всех платформах)
Вот код:

Код: Выделить всё

for(i=1;i<=num_snakes;i++) {
rsnake:
n=0;
printf("\tposition of snake %d:\t",i);
scanf("%d",&n);
if ((n<1) || (n>100)) {
fprintf(stderr,"Error: Invalid position entered: %d\n",n);
goto rsnake;
}
Понятно, что метки - это "грязный хак" и "не то что надо" но проблема проявляется даже если значение n проверять через цикл.

Если ввести какое-то большое число, то всё замечательно - отрабатывает и просит тоже самое значение опять.

НО!!! если ввести строку (это как бы валидэйшн - проверять его будут), то получается типа такого:
position of snake 1: Error: Invalid position entered
position of snake 1: Error: Invalid position entered
position of snake 1: Error: Invalid position entered
position of snake 1: Error: Invalid position entered

... и так до бесконечности. gdb показал, что scanf в этом случае значение переменной не изменяет (то есть остаётся 0, что нам и нужно, ибо это признак ошибки во вводимом значении), НО она просто выходит, ничего не спрашивая пользователя.

Помогите, пожалуйста!!! :oops:
Пытался что-то на MFC сорудить, но это такая гадость... нихрена не поймёшь, документации нормальной нет... Я даже не пойму как сделать аналог InputBox'a для VC++

ПО-МО-ГИ-ТЕ!!!

Добавлено: 16 янв 2005, 19:59
michael
Несколько отрывков из man scanf:

Код: Выделить всё

Scanning stops when an input  character  does  not  match such  a format character.
Что и происходит в твоем случае. При этом из stdin символы не удаляются и ты получаешь бесконечный цикл.

Код: Выделить всё

These functions return the number of input items assigned, which can be fewer than provided for, or even zero, in the event of a matching failure.  Zero indicates that, while there was input available, no  conversions  were assigned; typically this is due to an invalid input character, such as an alphabetic character for a `%d' conversion.
То есть необходимо проверять возвращаемое scanf значение и, если оно равно нулю, предпринимать специальные действия, например, очищать буфер. У меня сработала такая конструкция:

Код: Выделить всё

if(scanf("%d",&n)==0) scanf("%*[^\n]");

Добавлено: 16 янв 2005, 23:39
Pasha
Спасло while(getchar() != '\n') continue; //clear input buffer

:)

Спасибо товарищу Tren'у

Добавлено: 16 янв 2005, 23:39
Pasha
И чаво я ман почитать не догадался?..

Добавлено: 17 янв 2005, 19:01
[CWeR]
Pasha, может лучше fflush(stdin) использовать?

Добавлено: 17 янв 2005, 21:18
Pasha
Не работает fflush(stdin)...

Добавлено: 18 янв 2005, 15:29
[CWeR]
Pasha, странно :-/ у мня работает.

Добавлено: 18 янв 2005, 15:52
Pasha
кармы разные -)

ну я вообще уже с while прогу написал =)

Добавлено: 20 янв 2005, 21:15
d4s
а еще можно было lex на анализ прикрутить ;-) :oops:

Добавлено: 21 янв 2005, 02:16
Pasha
ага, под голую Microsoft Visual Studio :)