#c
#includeint main(void) { int num; do { scanf("%d", &num); if (num >= 1 && num <= 2000) { // Ниже тело цикла -------------------------- if (num <= 4) { printf("few\n"); } else if (num <= 9) { printf("several\n"); } else if (num <= 19) { printf("pack\n"); } else if (num <= 49) { printf("lots\n"); } else if (num <= 99) { printf("horde\n"); } else if (num <= 249) { printf("throng\n"); } else if (num <= 499) { printf("swarm\n"); } else if (num <= 999) { printf("zounds\n"); } else { printf("legion\n"); } } // закрывает "if (num >= 1 && num <= 2000)" } // закрывает "DO" while ((num < 1) || (num > 2000)); } Как-то по-уродски код вставился... Задача: На вход программа просит число. Если число в диапазоне от 1 до 2000, то следует выполнить тело цикла. И повторять это до тех пор, пока число меньше 1 или больше 2000. В целом все работает. Проблемы возникают тогда, когда я ввожу не число. К примеру "q". Тогда программа будет бесконечно просить меня ввести что-то, и ей уже все ровно, что я ввожу нужные значения. Не понимаю, почему не работает. Мой взгляд на вещи: Обьявляем переменную num Запускаем цикл DO Программа запрашивает данные (scanf) Допустим я ввожу "q" Т.к num - переменная типа int, я думаю до цикла if даже не дойдет Проверка на завершения цикла while, но т.к условию num явно не удовлетворяет, то цикл идет заного у меня опять запрашивают данные (scanf) и я ввожу "21" На этом этапе значение num должно пройти в цикл if и цикл while должен завершиться т.к соблюдаются условия по выходу из цикла вместо этого я получают цикл из бесконечных scanf.... и еще вопрос: почему я не получаю ошибку, когда пытаюсь ввести что-то, отличное от типа int? разве "&num" - это ни есть присвоение? всё уже должно было взорваться, когда я попытался впихнуть туда "q".
Ответы
Ответ 1
Нужно проверять, что возвращает scanf. Сделайте так: if (scanf("%d", &num) != 1) { while(fgetc(stdin) != '\n'); continue; } Т.е. пока не считано нормальное число - игнорировать введеннуюю строку и начать цикл заново... У вас, встретив не цифру, scanf оставляет ее в буфере, и при повторении цикла опять встречает ее же...Ответ 2
Вам следует проверять результат работы функции scanf, и если было введено не число, то пропускать введенные символы. Это можно сделать следующим образом int num; do { int result = scanf( "%d", &num ); if (result == EOF) break; if (result != 1) { scanf("%*[^\n]"); num == 0; } if (num >= 1 && num <= 2000) { // Ниже тело цикла -------------------------- if (num <= 4) { printf("few\n"); } else if (num <= 9) { printf("several\n"); } else if (num <= 19) { printf("pack\n"); } else if (num <= 49) { printf("lots\n"); } else if (num <= 99) { printf("horde\n"); } else if (num <= 249) { printf("throng\n"); } else if (num <= 499) { printf("swarm\n"); } else if (num <= 999) { printf("zounds\n"); } else { printf("legion\n"); } } // закрывает "if (num >= 1 && num <= 2000)" } while ((num < 1) || (num > 2000)); // закрывает "DO" В этом фрагменте кода, если было введено не число, то функция scanf Ничего не считает, а потому лна возвратит значение 0. В этом случае данное if предложение пропустит все неправильно введенные символы if (result != 1) { scanf("%*[^\n]"); num == 0; } и вы сможете повторить итерацию цикла.Ответ 3
scanf("%d", &num); Если мы уверены, что никаких EOF пользователь не введёт, то нам надо дождаться ввода числа (scanf вернёт 1) выкидывая нечисловые значения (ведь мусор, лежащий в потоке, сколько не пытайся его читать, числом-то не становится): while (scanf("%d", &num) != 1) scanf("%*s"); Если мы хотим ещё и EOF проверять (который -1), то можно немного переписать условие: while (scanf("%d", &num) == 0) scanf("%*s"); или while (!scanf("%d", &num)) scanf("%*s"); Если хочется порпускать всю строку целиком, то можно использовать while (!scanf("%d", &num)) scanf("%*[^\r\n]"); Как-то так.Ответ 4
Да эта беда всегда была в scanf и им поэтому никто не пользуется, он выпихивает назад что ему не нравится по ungetc, короче надо строчку через gets ввести, а потом её в sscanf