Обнаружение Enter в случае переключения в C? - PullRequest
0 голосов
/ 27 октября 2019

У меня больше проблем с этим, чем я, вероятно, должен был бы. Я создаю очень простой интерфейс банковского меню, где пользователь может проверить свой баланс, внести депозит, вывести или выйти из меню. case 1, case2 и case3 работают нормально, но case 4 не работает должным образом, независимо от того, что я пытаюсь использовать в Google.

В этой текущей версии printf()происходит оператор в case 4, тогда, кажется, больше ничего не происходит, пока я не введу один из других параметров (1 - 3) дважды, после чего цикл будет циклически повторяться и автоматически использовать любой второй вход. Я попытался getchar(), но это не сработало (или я не реализовал это правильно).

Почему происходит такое поведение и как я могу это исправить?

Воткод:

#include <stdio.h>
#include <cs50.h>

double deposit(double a, double b);
double withdraw(double a, double b);

int main(void)
{
    int resume = 1;
    int user_input = 0;
    double user_balance = 10.00;
    printf("Welcome to UBank!\n");

    while (resume)
    {
        printf("\n====================\n");
        printf("Select an operation:\n\n1. Show Balance\n2. Make a Deposit\n3. Make a Withdrawal\n4. Quit\n"
               "====================\n\n");
        scanf("%d", &user_input);

        int quit_character = 0x00;
        double deposit_amount = 0.00;
        double withdraw_amount = 0.00;

        switch (user_input)
        {
            case 1:
                printf("Balance: $%.2lf\n", user_balance);
                break;
            case 2:
                printf("How much would you like to deposit?\n");
                scanf("%lf", &deposit_amount);
                user_balance = deposit(user_balance, deposit_amount);
                break;
            case 3:
                printf("How much would you like to withdraw?\n");
                scanf("%lf", &withdraw_amount);
                user_balance = withdraw(user_balance, withdraw_amount);
                break;
            case 4:
                printf("Press Enter to finish banking or any other key to continue.\n");
                scanf("%d\n", &quit_character);
                if (quit_character == 0x0A)
                {
                    resume = 0;
                }
                break;
        }
    }
}

double deposit(double a, double b)
{
    if (b > 0 && b < 10000)
    {
        return a + b;
    }
    else
    {
        printf("Please enter a valid amount. (0.01 - 9999.99)\n");
        return a;
    }
}

double withdraw(double a, double b)
{
    if (b > 0 && a - b >= 10)
    {
        return a - b;
    }
    else if (b <= 0)
    {
        printf("Withdrawal amount must be greater than $0.00.\n");
    }
    else if (a - b < 10)
    {
        printf("Withdrawal amount invalid.  Remaining balance must be $10.00 or more.\n");
    }
    return a;
}

1 Ответ

1 голос
/ 27 октября 2019

Предположим, я хочу покрасить экстерьер своего дома. Я покупаю краску и возвращаюсь домой (в 5 часах езды от ближайшего магазина). Когда я прихожу домой, я понимаю, что забыл купить кисть. Я не хочу тратить следующие 10 часов за рулем, чтобы получить кисть, но как мне наносить краску?

Я мог бы использовать метлу, швабру, тряпку, руки, руки сына и т. Д., Ни одна из которых не предпочтительнее кисти. Но потом я понимаю ... у меня есть лошадь! Я обрезаю лошадь и делаю свою кисть! Я рисую в течение дня и снова обрезаю лошадь на следующей неделе, когда мне нужна еще одна кисть. Это оказывается намного дешевле, чем 10-часовая поездка.

ОК ... это банальная, вымышленная история. Дело в том, что использование scanf () для пользовательского ввода похоже на рисование со свиным носом. Это просто неправильный инструмент для работы. Было бы предпочтительнее написать собственную функцию пользовательского ввода, которая работает так, как вы ожидаете.

Рассмотрим функцию GetInput () ниже. Я должен был сделать это сам, но он наверняка превосходит использование scanf () для пользовательского ввода:

  #include <stdio.h>
  #include <stdlib.h>

  double deposit(double a, double b);
  double withdraw(double a, double b);

  /*-----------------------------------------------------------------------------------
  ** Get input from user, and return it as specific types.  
  **
  ** Caller may specify NULL for any (or all) input types that are not needed.
  */
  void GetInput(int *intOut, char *charOut, double *doubleOut)
    {
    // Pointer to a temporary (allocated memory) buffer to hold user input.
    char    *line_A   = NULL;

    // Number of bytes allocated to the temporary (allocated) buffer.
    size_t   lineSize = 0;

    // Holds the number of bytes entered by the user, or (-1) for error.
    ssize_t  lineLength;

    lineLength=getline(&line_A, &lineSize, stdin);
    if(-1 == lineLength)
       {
       fprintf(stderr, "getline() failed.\n"
       goto CLEANUP;
       }

    // If the caller did not specify NULL for intOut, ...
    if(intOut)
      // Convert the string to an int and pass it back to the caller.
      *intOut = atoi(line_A); 

    if(charOut)
      *charOut = *line_A;

    if(doubleOut)
      *doubleOut = atof(line_A);

  CLEANUP:
    if(line_A)
      free(line_A);

    return;
    }

  int main(void)
  {
      int resume = 1;
      int user_input = 0;
      double user_balance = 10.00;
      printf("Welcome to UBank!\n");

      while (resume)
      {
          printf("\n====================\n");
          printf("Select an operation:\n\n1. Show Balance\n2. Make a Deposit\n3. Make a Withdrawal\n4. Quit\n"
                 "====================\n\n");
          GetInput(&user_input, NULL, NULL);     // Get an integer from the user.

          char quit_character = 0x00;
          double deposit_amount = 0.00;
          double withdraw_amount = 0.00;

          switch (user_input)
          {
              case 1:
                  printf("Balance: $%.2lf\n", user_balance);
                  break;
              case 2:
                  printf("How much would you like to deposit?\n");
                  GetInput(NULL, NULL, &deposit_amount);  // Get a double from the user.
                  user_balance = deposit(user_balance, deposit_amount);
                  break;
              case 3:
                  printf("How much would you like to withdraw?\n");
                  GetInput(NULL, NULL, &withdraw_amount);  // Get a double from the user.
                  user_balance = withdraw(user_balance, withdraw_amount);
                  break;
              case 4:
                  printf("Press Enter to finish banking or any other key to continue.\n");
                  GetInput(NULL, &quit_character, NULL);  //Get a character from the user.
                  if (quit_character == 0x0A)
                  {
                      resume = 0;
                  }
                  break;
          }
      }
  }

  double deposit(double a, double b)
  {
      if (b > 0 && b < 10000)
      {
          return a + b;
      }
      else
      {
          printf("Please enter a valid amount. (0.01 - 9999.99)\n");
          return a;
      }
  }

  double withdraw(double a, double b)
  {
      if (b > 0 && a - b >= 10)
      {
          return a - b;
      }
      else if (b <= 0)
      {
          printf("Withdrawal amount must be greater than $0.00.\n");
      }
      else if (a - b < 10)
      {
          printf("Withdrawal amount invalid.  Remaining balance must be $10.00 or more.\n");
      }
      return a;
  }
...