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

Все о программировании под *nix
Аватара пользователя
Pasha
Неотъемлемая часть форума
Сообщения: 554
Зарегистрирован: 06 окт 2002, 12:39
Откуда: Southampton
Контактная информация:

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

Сообщение 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++

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

michael
Неотъемлемая часть форума
Сообщения: 434
Зарегистрирован: 12 апр 2004, 11:00
Откуда: г. Владивосток
Контактная информация:

Сообщение 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]");

Аватара пользователя
Pasha
Неотъемлемая часть форума
Сообщения: 554
Зарегистрирован: 06 окт 2002, 12:39
Откуда: Southampton
Контактная информация:

Сообщение Pasha »

Спасло while(getchar() != '\n') continue; //clear input buffer

:)

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

Аватара пользователя
Pasha
Неотъемлемая часть форума
Сообщения: 554
Зарегистрирован: 06 окт 2002, 12:39
Откуда: Southampton
Контактная информация:

Сообщение Pasha »

И чаво я ман почитать не догадался?..

[CWeR]
Заглянувший
Сообщения: 29
Зарегистрирован: 20 дек 2004, 19:53
Откуда: Минск
Контактная информация:

Сообщение [CWeR] »

Pasha, может лучше fflush(stdin) использовать?

Аватара пользователя
Pasha
Неотъемлемая часть форума
Сообщения: 554
Зарегистрирован: 06 окт 2002, 12:39
Откуда: Southampton
Контактная информация:

Сообщение Pasha »

Не работает fflush(stdin)...

[CWeR]
Заглянувший
Сообщения: 29
Зарегистрирован: 20 дек 2004, 19:53
Откуда: Минск
Контактная информация:

Сообщение [CWeR] »

Pasha, странно :-/ у мня работает.

Аватара пользователя
Pasha
Неотъемлемая часть форума
Сообщения: 554
Зарегистрирован: 06 окт 2002, 12:39
Откуда: Southampton
Контактная информация:

Сообщение Pasha »

кармы разные -)

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

d4s
Маньяк
Сообщения: 184
Зарегистрирован: 11 авг 2003, 12:12
Откуда: Минск
Контактная информация:

Сообщение d4s »

а еще можно было lex на анализ прикрутить ;-) :oops:
WBR, d4s
linux registered user #264610 [Empty]

Аватара пользователя
Pasha
Неотъемлемая часть форума
Сообщения: 554
Зарегистрирован: 06 окт 2002, 12:39
Откуда: Southampton
Контактная информация:

Сообщение Pasha »

ага, под голую Microsoft Visual Studio :)

Ответить