Я использую цикл, чтобы определить, правильный ли ввод, и, если он неправильный, запрашиваю еще раз, пока ввод не станет действительным, программа запускается, но мне приходится вводить число несколько раз. Если я запускаю код на другой машине, он работает без проблем даже при первом вводе. Вот пример, но он один и тот же, независимо от того, какой цикл я выберу.
while (input != 1 || getchar() != '\n') {
while ((c = getchar()) != '\n' && c != EOF) { }
input = scanf ("%d", &number);
if (input != 1 || getchar() != '\n') {
printf ("Try again!\n");
}
}
Изменена структура кода и изменены условия цикла и тело цикла, но все равно несколько раз ввод или один запуск.
#include <stdio.h>
интервал основной() {
char c;
int input = 0, loopvariable = 1, number, secondtolastfibo = 1, lastbuttwofibo = 1;
long lastfibo;
printf ("Fibonacci-Numbers\n"
"How many Fibonacci do you want? ");
while (input != 1 || getchar() != '\n') {
while ((c = getchar()) != '\n' && c != EOF) { }
input = scanf ("%d", &number);
if (input != 1 || getchar() != '\n') {
printf ("Try a positive number!\n");
}
}
secondtolastfibo = 1;
lastbuttwofibo = 1;
printf ("%d. \t%d\n", loopvariable, secondtolastfibo);
loopvariable++;
printf ("%d. \t%d\n", loopvariable, secondtolastfibo);
while (loopvariable < number) {
fflush(stdin);
loopvariable++;
lastfibo = secondtolastfibo + lastbuttwofibo;
lastbuttwofibo = secondtolastfibo;
secondtolastfibo = lastfibo;
printf ("%d. \t%ld\n", loopvariable, lastfibo);
if (loopvariable % 10 == 0) {
printf ("Continue with Return.......");
getchar();
}
}
return 0;
}
Вход и выход: Числа Фибоначчи Сколько чисел Фибоначчи вы хотите? 23\н 23\н
1
1
2
...
Изменены условия цикла: избавились от « while ((c = getchar()) != '\n' && c != EOF)» или изменили условие цикла на (input !=1) или поместили input = scanf(. ..) вне цикла и условие цикла (input !=1), но это не сработало, и для запуска все равно приходилось вводить несколько раз.
Пожалуйста, отредактируйте свой вопрос и создайте минимальный воспроизводимый пример. Невозможно знать наверняка, в чем проблема, если мы не можем запустить тот же код, что и вы.
Добро пожаловать в СО. Это утверждение: «Изменил структуру кода и изменил условия цикла и тело цикла», по сути, идентично утверждению «Я сделал какие-то случайные вещи, о которых вам не говорю». Если вы не сообщите нам, какие изменения вы внесли, это предложение бесполезно для любого читателя.
Вы потребляете и отбрасываете часть входных данных с помощью вызовов getchar. Вы можете просто использовать scanf здесь.
@interjay Мне нужно убедиться, что на входе находятся только целые числа, а не, например, 34erfd, поэтому getchar(). Я также мог бы использовать char, но это не решает проблему.
Но getchar избавляется как от целых, так и от нецелых чисел.





Набор сканирования %1[\n] выполнит поиск одного символа, который должен быть символом новой строки. Сканирование добавит ноль к выходным данным, поэтому char newline[2] — это необходимый минимум. %*[^\n] просканирует и отбросит все, что не является переводом строки.
#include <stdio.h>
int main ( void) {
char newline[2] = "";
int input = 2, loopvariable = 1, number = 0, secondtolastfibo = 1, lastbuttwofibo = 1;
long lastfibo = 0;
printf ("Fibonacci-Numbers\n"
"How many Fibonacci do you want? ");
do {
if ( input != 2) {
scanf ( "%*[^\n]"); // scan and discard everything not a newline
printf ( "\tTry again\n");
}
input = scanf ("%d%1[\n]", &number, newline); // scan for integer and a newline
if (input == EOF) {
fprintf ( stderr, "EOF\n");
return 1;
}
} while (input != 2);
secondtolastfibo = 1;
lastbuttwofibo = 1;
printf ("%d. \t%d\n", loopvariable, secondtolastfibo);
loopvariable++;
printf ("%d. \t%d\n", loopvariable, secondtolastfibo);
while (loopvariable < number) {
loopvariable++;
lastfibo = secondtolastfibo + lastbuttwofibo;
lastbuttwofibo = secondtolastfibo;
secondtolastfibo = lastfibo;
printf ("%d. \t%ld\n", loopvariable, lastfibo);
if (loopvariable % 10 == 0) {
do {
printf ("Continue with Return.......");
scanf ( "%*[^\n]"); // scan and discard everything not a newline
input = scanf ( "%1[\n]", newline); // scan for one character that muse be a newline
if (input == EOF) {
fprintf ( stderr, "EOF\n");
return 1;
}
} while (input != 1);
}
}
return 0;
}
Спасибо за помощь. Но знаете ли вы, что было не так с моим кодом, что мне пришлось вводить данные несколько раз?
@Nemu Наборы сканов и спецификаторы формата позволяют ограничить количество читаемых символов. %d будет читать только цифры и + или -. %[ /f/t/r/v]будет читать только пробелы, а не новую строку. Другое отличие состоит в том, что при сбое сканирования проблемный символ заменяется во входном потоке. Если %1[\n] читает что-то кроме новой строки или первый символ, прочитанный %d, не является целым числом, прочитанный символ возвращается для чтения при следующем сканировании. getchar читает символ из входного потока, и этот символ исчезает.
Я рекомендую вам использовать
fgets, чтобы прочитать всю строку, а затем использовать, например.sscanfилиstrtol, чтобы преобразовать входные данные в число с проверкой. Таким образом, ваш код станет намного проще, и вам не понадобятся два цикла или все эти вызовыgetchar(которые являются вероятными виновниками).