Проблема с циклом if-else в управляемом пользователем цикле do-while

Мой псевдокод:

Лучший случай: 1) Спросите у пользователя номер 2) Проверьте, является ли ввод пользователя числовым значением 3) Если ввод пользователя действителен, выполните функции пола, круга и потолка при вводе пользователя. 4) Отображение значений пола, круглых и потолочных значений пользовательского ввода

Худший случай: 1) Спросите у пользователя номер 2) Проверьте, является ли ввод пользователя числовым значением 3) Если ввод пользователя недействителен, спросите, хочет ли пользователь повторить попытку, выбрав Да/Нет. 4) Если пользователь говорит да, вернуться к 1), если пользователь говорит нет - завершить

#include <stdio.h>
#include <math.h>

int main(void) {

    float user_input;
    int a;
    char answ;

    do {
        printf ("Enter a number to find its lower bound, rounded, and upper bound values: ");

        if ((a = scanf("%f", &user_input) == 1)) {

            float floored_input = floor(user_input);
            float rounded_input = round(user_input);
            float ceiled_input = ceil(user_input);

            printf("Lower Bound: %1.0f\n", floored_input);
            printf("Rounded:     %1.0f\n", rounded_input);
            printf("Upper Bound: %1.0f\n", ceiled_input);

            break;

        } else {

            printf("Invalid input. Do you want to try again? (Y/N): ");
            scanf("%c", &answ);

        }
    } while(answ == 'Y' || answ == 'y');

    return 0;
}

Единственная проблема, с которой я сталкиваюсь, заключается в том, что когда пользователь вводит буквально значение, отличное от «i», программа завершается, и я возвращаюсь в свой рабочий каталог.

Пользователь может ввести любое число, и оно сработает. Пользователь может ввести i, и ему будет предложено выбрать вариант Y/N.

ОДНАКО, когда пользователь вводит «i2», «hello», «h», «b», «yoooo» и т. д.

Пользователь не получает вариант Y/N, и программа завершается.

Добавьте пробел к scanf(" %c", &answ);, чтобы отфильтровать начальные пробелы. См. scanf() оставляет символ новой строки в буфере. Также обратите внимание, что char answ — неинициализированная переменная для циклов, которые не вводят значение. Это должно быть определено как char answ = 'y';

Weather Vane 28.05.2019 20:09

Вам нужно больше скобок в (a = scanf("%f", &user_input) == 1). == имеет более высокий приоритет, чем =.

Rup 28.05.2019 20:10

Все еще не работает. Подсказка Y/N появляется только тогда, когда пользователь вводит букву «i».

Tommy Son 28.05.2019 20:12

Кроме того, если scanf("%f", &user_input) не возвращает 1, возможно, что-то застряло в буфере, что будет подхвачено scanf(" %c", &answ);

Weather Vane 28.05.2019 20:14

Я попытался добавить больше скобок: if (a = (scanf("%f", &user_input) == 1)) и все равно дает те же результаты

Tommy Son 28.05.2019 20:16

Переменная a не используется и может быть удалена. Кстати, вы еще не расставили скобки в нужном месте, поэтому удаление a — ваш лучший вариант. Это не решит проблему, конечно. Чтобы решить проблему (когда пользователь вводит недопустимое число), код должен читаться до тех пор, пока не будет найдена новая строка, или код должен читать строку с fgets и анализировать ее с помощью sscanf

user3386109 28.05.2019 20:17

удаление разрыва все равно не решает проблему

Tommy Son 28.05.2019 20:21

я вынул переменную <code>a</code>, а также в моей функции if: <code>if (scanf("%f", &user_input) == 1)</code> и она все еще делает то же самое. Хотя вынимать «код за кодом» приятно

Tommy Son 28.05.2019 20:23

Когда вы вводите «i2», scanf(" %c", answ); удаляет только первый символ неправильного ввода. Я предлагаю вам перестать бороться с scanf и получить ввод с fgets и применить sscanf к строке. Гораздо проще сбросить строку и получить другой ввод, чем возиться с очисткой входного буфера. Но не смешивайте fgets с scanf, используйте fgets для всех ответов пользователей.

Weather Vane 28.05.2019 20:25
Вот пример использования fgets с sscanf из несколько связанного вопроса.
user3386109 28.05.2019 20:30

@TommySon делает Этот ответ помогает?

Michi 28.05.2019 20:48

Я добавил: fgets(input, INPUT_SIZE, stdin); if ((sscanf(input, "%f", &user_input)) == 1) { .....} и теперь мне будет предложено ввести неверный ввод, спасибо. НО, если бы я ввел недопустимый ввод и снова выбрал число, когда будет предложено, отображается следующая строка: «Введите число, чтобы найти его нижнее, округленное и верхнее значения: неверный ввод. Вы хотите попробовать еще раз? (Д/Н): " и когда я ввожу y или Y, та же самая строка повторяется

Tommy Son 28.05.2019 20:50

@TommySon Как насчет чего-нибудь Так?

Michi 28.05.2019 21:01

@Мичи, извини, это немного сбивает меня с толку.

Tommy Son 28.05.2019 21:20

OT: функция: floor(), round() и ceil() возвращает double не float Предлагает 1) прочитать страницу MAN для функций, которые вы используете, и 2) предлагает: floorf() и roundf() и ceilf()

user3629249 29.05.2019 01:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
15
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

следующий предлагаемый код:

  1. чисто компилирует
  2. выполняет желаемую функцию
  3. использует заголовочный файл: ctype.h функция: toupper()
  4. использует правильные функции для значений float
  5. правильно инициализирует переменную: answ

и теперь предлагаемый код:

#include <stdio.h>
#include <math.h>
#include <ctype.h>

int main(void) 
{
    float user_input;
    char answ = 'Y';

    while( toupper( answ ) != 'N' ) 
    {
        printf ("Enter a number to find its lower bound, rounded, and upper bound values: ");

        if ( scanf("%f", &user_input) == 1 ) 
        {
            float floored_input = floorf( user_input );
            float rounded_input = roundf( user_input );
            float ceiled_input  = ceilf(  user_input );

            printf( "Lower Bound: %1.0f\n", floored_input );
            printf( "Rounded:     %1.0f\n", rounded_input );
            printf( "Upper Bound: %1.0f\n", ceiled_input );
        } 

        do
        {
            printf( "Do you want to try again? {Y/N}: " );
            scanf( " %c", &answ );
            //printf( "debug: answ = %x\n", answ );
        } while( toupper(answ) != 'Y' && toupper( answ ) != 'N' );
    }
    return 0;
}

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