【问题标题】:Infinite looping when Switch case is given wrong input当 Switch case 输入错误时无限循环
【发布时间】:2012-08-10 10:19:31
【问题描述】:

我有一个非常简单的代码段,其中有一个带有 switch case 的 do while 循环,如下所示:

do {
    printf("Enter Choice\n");
    scanf("%d", &choice);
    switch(choice) {
          case 1: printf("1 selected");
                  break;
          case 2: printf("exit");
                  break;
          default: printf("wrong input");
                  break;
    }
} while (choice != 2);

在这段代码中,如果我不小心输入了一个字符而不是一个数字,程序就会无限期地陷入混乱,甚至不接受输入。 我知道如果我插入,这可以纠正

if(isdigit(choice))

在进入开关盒之前。但我的问题是,为什么它首先会发生。

不应该去默认情况下再次要求输入吗?

【问题讨论】:

  • 我看不出if(isdigit(choice)) 怎么可能解决这个问题,因为choice 是已经解释的整数输入,而不是char
  • 当您收到与您的格式规范不同的输入时,您会遇到问题,所以换句话说,不,为了解决这个问题,它必须是正确的格式。我会说接受所有内容作为字符串。这样就不会出现错误。然后,您检查输入字符串,根据需要进行转换......等等......

标签: c switch-statement


【解决方案1】:

如果scanf 无法将输入与格式说明符匹配,则将其留在缓冲区中。所以下一次它仍然不会匹配等等。换句话说,它不吃它无法匹配的东西。您必须检查 scanf 返回的值,即匹配项的数量,以确保输入是预期的。

或者,要跳过不需要的东西,您可以尝试(未经测试):

scanf("%*[^0-9]%d", &choice);

这应该在尝试读取十进制整数之前丢弃任何不是数字的内容。

【讨论】:

    【解决方案2】:

    请查看scanf 手册页。

    如果在这种情况下输入中的下一个不是数字,则不会消耗它。

    您需要检查scanf 的返回值,如果为零,则使用下一个字符并重试(或者可能直到到达行尾)。

    【讨论】:

      【解决方案3】:

      我试过 if(isdigit(choice)) 但问题仍然存在。 此问题与缓冲区有关,如果输入的数据类型与 scanf 中的格式说明符不匹配,则输入不会被 scanf 消耗并保留在缓冲区中。

      为了解决这个问题,我尝试了 fflush(stdin),它适用于 windows 中的 c 编译器,但不适用于 linux,对不起,我不知道 fflush(stdin) 不适用于 linux 的原因。

      我还尝试了在 Windows 和 linux 上运行良好的 getchar(),我将 getchar() 放在循环内的语句末尾。

       do 
          {
             printf("Enter Choice\n");
          scanf("%d", &choice);
              switch(choice) {
                    case 1: printf("1 selected");
                            break;
                    case 2: printf("exit");
                            break;
                    default: printf("wrong input");
                            break;
              }
      
          getchar();
          } while (choice != 2);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-04
        • 1970-01-01
        • 2012-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多