Ввод кода VS необходимо выполнить несколько раз

Я использую цикл, чтобы определить, правильный ли ввод, и, если он неправильный, запрашиваю еще раз, пока ввод не станет действительным, программа запускается, но мне приходится вводить число несколько раз. Если я запускаю код на другой машине, он работает без проблем даже при первом вводе. Вот пример, но он один и тот же, независимо от того, какой цикл я выберу.

  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.  1
    
  3.  2
    

...

Изменены условия цикла: избавились от « while ((c = getchar()) != '\n' && c != EOF)» или изменили условие цикла на (input !=1) или поместили input = scanf(. ..) вне цикла и условие цикла (input !=1), но это не сработало, и для запуска все равно приходилось вводить несколько раз.

Я рекомендую вам использовать fgets, чтобы прочитать всю строку, а затем использовать, например. sscanf или strtol, чтобы преобразовать входные данные в число с проверкой. Таким образом, ваш код станет намного проще, и вам не понадобятся два цикла или все эти вызовы getchar (которые являются вероятными виновниками).

Some programmer dude 07.05.2024 12:15

Пожалуйста, отредактируйте свой вопрос и создайте минимальный воспроизводимый пример. Невозможно знать наверняка, в чем проблема, если мы не можем запустить тот же код, что и вы.

user694733 07.05.2024 12:18

Добро пожаловать в СО. Это утверждение: «Изменил структуру кода и изменил условия цикла и тело цикла», по сути, идентично утверждению «Я сделал какие-то случайные вещи, о которых вам не говорю». Если вы не сообщите нам, какие изменения вы внесли, это предложение бесполезно для любого читателя.

Gerhardh 07.05.2024 12:57

Вы потребляете и отбрасываете часть входных данных с помощью вызовов getchar. Вы можете просто использовать scanf здесь.

interjay 07.05.2024 15:05

@interjay Мне нужно убедиться, что на входе находятся только целые числа, а не, например, 34erfd, поэтому getchar(). Я также мог бы использовать char, но это не решает проблему.

Nemu 07.05.2024 17:31

Но getchar избавляется как от целых, так и от нецелых чисел.

interjay 07.05.2024 17:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Набор сканирования %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 08.05.2024 18:59

@Nemu Наборы сканов и спецификаторы формата позволяют ограничить количество читаемых символов. %d будет читать только цифры и + или -. %[ /f/t/r/v]будет читать только пробелы, а не новую строку. Другое отличие состоит в том, что при сбое сканирования проблемный символ заменяется во входном потоке. Если %1[\n] читает что-то кроме новой строки или первый символ, прочитанный %d, не является целым числом, прочитанный символ возвращается для чтения при следующем сканировании. getchar читает символ из входного потока, и этот символ исчезает.

user3121023 09.05.2024 00:00

Другие вопросы по теме