Как бы мне исправить этот оператор if в C, чтобы заставить его работать так, как задумано?

#c #if-statement

#c #if-statement

Вопрос:

В этом фрагменте кода для «системы управления контактами» у меня возникают трудности с получением предполагаемого вывода для строки. В принципе, во время этой части, когда вы добавляете новый контакт, он просит вас «пожалуйста, введите номер квартиры», как показано ниже:

  if (yes() == 1)
 {
     printf("Please enter the contact's apartment number: ");
     address->apartmentNumber = getInt();
     if (address->apartmentNumber > 0)
     {
     }
     else
     {
        printf("*** INVALID INTEGER *** <Please enter an integer>: ");
        address->apartmentNumber = getInt();
    }
  }
  else
  {
      address->apartmentNumber = 0;
  }
  

Теперь, согласно моему заданию, вы должны ввести слово (вместо числа, понимаете?) «bison», который выводит результат:

* НЕДОПУСТИМОЕ ЦЕЛОЕ ЧИСЛО * Пожалуйста, введите целое число:

Для контекста эта часть работает абсолютно нормально. Однако затем вам предлагается ввести целое число «-1200», которое затем должно вызвать приглашение

* НЕВЕРНЫЙ НОМЕР КВАРТИРЫ * Пожалуйста, введите положительное число:

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

Я попытался исправить проблему самостоятельно, но это просто дает мне удвоение недопустимого целочисленного вывода вместо этого правильного оператора с недопустимым номером квартиры. Вот моя (неудачная) попытка:

     if (yes() == 1)
    {
        printf("Please enter the contact's apartment number: ");
        address->apartmentNumber = getInt();

        if (address->apartmentNumber > 0)
        {
        }
        else
        {
            printf("*** INVALID INTEGER *** <Please enter an integer>: ");
            address->apartmentNumber = getInt();
        }
        if (address->apartmentNumber < 0)
        {
        }
        else
        {
            printf("*** INVALID APARTMENT NUMBER *** <Please enter a positive number>: ");
            address->apartmentNumber = getInt();       
        }
        else
        {
            address->apartmentNumber = 0;
        }
  

РЕДАКТИРОВАТЬ: Для тех, кто запрашивал код для getInt() и yes(), здесь:

getInt()

 int getInt(void)
{
    int num;
    char nl;

    scanf("%d%c", amp;num, amp;nl);
    while (nl != 'n') {
        clearKeyboard();

        printf("*** INVALID INTEGER *** <Please enter an integer>: ");
        scanf("%d%c", amp;num, amp;nl);
    }
    return num;
}
  

и да ():

 int yes(void)
{
    int yesno, flag;
    char c, nl;
    scanf("%c%c", amp;c, amp;nl);

    do {
        if (nl != 'n') {
            clearKeyboard();

            printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: ");
            flag = 1;
            scanf("%c%c", amp;c, amp;nl);
        }
        else if (c != 'Y' amp;amp; c != 'y' amp;amp; c != 'N' amp;amp; c != 'n') {
            printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: ");
            flag = 1;
            scanf("%c%c", amp;c, amp;nl);
        }
        else if (nl == 'n' amp;amp; (c == 'Y' || c == 'y' || c == 'N' || c == 'n')) 
        {
            flag = 0;
        }
    } while (flag == 1);

    if (c == 'Y' || c == 'y') {
        yesno = 1;
    }
    else {
        yesno = 0;
    }
    return yesno;
}
  

Комментарии:

1. Да? Вам нужно немного подтянуть это. И что делает yes() и getInt() ?

2. Это функции. это абсолютно масштабное назначение с большим количеством кода на нескольких c и заголовочных файлах. вы могли бы притвориться, что их там нет, и импровизировать, как будто они не нужны, если это вообще поможет

3. Любое подходящее исправление должно распространяться в getInt (). Подсказка: число 0.

4. Можете ли вы поделиться кодом для getInt , и желательно также для yes ?

5. @Джошуа Да? Меня смущает это утверждение. Я хотел бы привести пример того, что вы имеете в виду

Ответ №1:

getInt позаботится о нецелом вводе (текст и слова) и перепрошивает пользователя для ввода целого числа, пока он этого не сделает.

Итак, ваш код должен быть больше похож на этот:

 if (yes() == 1)
{
     int validNumber = 0;
     while (validNumber == 0)
     {
         printf("Please enter the contact's apartment number: ");
         address->apartmentNumber = getInt();
         if (address->apartmentNumber > 0)
         {
             validNumber = 1;
         }
         else
         {
             printf("* INVALID APARTMENT NUMBER * Please enter a positive number:n");
         }
     }
}
  

Комментарии:

1. это может сработать, но это говорит мне, что допустимый ввод не определен. где я должен это определить? «bool», «false» и «true» говорят, что они не определены, что вызывает ошибку при построении решения

2. Это буквально определено для вас как bool validInput = false; Что еще вам нужно?

3. Я имею в виду, что в Visual Studio красным выделены значения bool, false и true. Всякий раз, когда я навожу курсор на любой из этих 3, он говорит, что они не определены и выдают мне ошибки, с учетом которых я не могу создать решение, а затем перехожу к отладке. вот что я имею в виду…

4. Я склонен полагать, что вы еще не прошли стадию изучения языка Си «привет, мир». Ознакомились ли вы с базовыми концепциями программирования, такими как циклы, логические значения, условная логика и т.д… Я изменил validNumber значение на целое на случай, если ваш компилятор C еще не распознает синтаксис bool в C. Если это не сработает, вы сами должны изучить основы структуры программы и объявления переменных.

5. @Aaron — да, сделай это.

Ответ №2:

Ваша getint() функция ужасно хрупкая. Что означает, что пользователь вводит нецелочисленное значение только один раз? При вводе определенного типа обычно лучше выполнять непрерывный цикл, пока вы не получите действительный ввод (или пользователь отменит ввод), и всегда защищаться от того, что ввод не соответствует вашим ожиданиям (например, когда кошка наступает на клавиатуру …)

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

  1. (return == EOF) пользователь отменил ввод, сгенерировав ввод вручную, EOF нажав Ctrl d (или в WindowsCtrl z, но см. CTRL Z не генерирует EOF в Windows 10 (ранние версии));
  2. (return < expected No. of conversions) произошел сбой сопоставления или ввода. При сбое сопоставления вы должны учитывать каждый символ, оставшийся в вашем входном буфере. (сканируйте вперед во входном буфере, считывая и отбрасывая символы, пока не будет найдено 'n' or EOF ); и, наконец
  3. (return == expected No. of conversions) указывает на успешное чтение — затем вам предстоит проверить, соответствует ли ввод каким-либо дополнительным критериям (например, положительное целое число, положительная плавающая точка, в пределах необходимого диапазона и т.д.).

Используя это для работы с вашей getint() функцией и передавая символьную строку для отображения в виде приглашения пользователя (если нет NULL ), вы могли бы сделать что-то похожее на:

 int getint (int *value, const char *prompt)
{
    /* loop continually until good input or canceled */
    for (;;) {
        int rtn;        /* variable for return from scanf */
        if (prompt)                     /* if not NULL    */
            fputs (prompt, stdout);     /* display prompt */
        rtn = scanf ("%d", value);      /* attempt read   */

        if (rtn == EOF) {   /* check for manual EOF */
            fputs ("<user canceled input>n", stderr);
            return 0;
        }
        empty_stdin();  /* all other cases - empty input buffer */
        if (rtn == 1)   /* good input, break */
            break;
        /* otherwise matching failure */
        fputs ("  error: invalid integer input.n", stderr);
    }
    return *value;  /* value also available through pointer */
}
  

(примечание: значение, возвращаемое из функции, является проверкой того, была ли функция выполнена успешно (возврат 1 ) или пользователь отменил с помощью EOF (возврат 0 ), целочисленное значение становится доступным вызывающему через указатель value )

Вспомогательная функция empty_stdin() просто:

 void empty_stdin (void)
{
    int c = getchar();
    while (c != 'n' amp;amp; c != EOF)
        c = getchar();
}
  

Есть много способов собрать getint() вместе, чтобы адаптировать его к вашим потребностям, пока вы правильно обрабатываете все три случая, описанные выше, вы вольны делать это любым удобным для вас способом.