while循环在获取getchar()之前重复printf两次?

时间:2013-07-26 23:04:02

标签: c while-loop

我目前正在学习C和C ++。在这个小小的“程序实践”中,我要求用户输入'i'或'd'来知道他们是想使用整数还是十进制(浮点数)。我有一个while循环,通过告诉他们输入错误的char来确保用户输入'i'或'd'。出于某种原因,while循环内的提示在转到getchar()之前打印两次。在这种情况下,我有点难以理解幕后发生的事情。任何帮助都非常感激。我正在使用Xcode(不知道它是否相关)。

#include <stdio.h>

int main()
{

  char action;

  printf("Please enter 'i' to work with integers or 'd' to work with decimals.\n\n"); 

  scanf("%c", &action); 

   while (action != 'i' || action != 'd')
   {
     printf("You didn't entered the right command. Please try again (i/d)\n");
     action = getchar()
   }
 }

所以我作为输出得到的是:

You didn't entered the right command. Please try again (i/d)
You didn't entered the right command. Please try again (i/d)

3 个答案:

答案 0 :(得分:4)

当您输入一个角色并点击一个回归时,您实际上输入了两个字符 - 字符和返回字符('\ n')。循环对每个字符执行一次。这就是为什么你看到它经历了两次。

诀窍是明确过滤掉返回字符,如下所示:

#include <stdio.h>

int main()
{

  char action;

  printf("Please enter 'i' to work with integers or 'd' to work with decimals.\n\n"); 

  scanf("%c", &action); 

   while (action != 'i' || action != 'd')
   {
     if (action != '\n')
     {
       printf("You didn't entered the right command. Please try again (i/d)\n");
     }
     action = getchar();
   }
}

答案 1 :(得分:1)

正如Ziffusion answer中{{3}}正确诊断的那样,您会得到双提示,因为您在用户输入不正确的单独字符后得到换行符,而且i也不是也不是d

这是一个改写,有一些改进:

#include <stdio.h>

int main(void)
{
    char action = '\0';

    printf("Please enter 'i' to work with integers or 'd' to work with decimals: "); 

    while (scanf(" %c", &action) == 1 && action != 'i' && action != 'd')
        printf("You didn't enter the right command. Please try again (i/d): ");

    printf("Action selected: %d\n", action);
}

发生了什么变化?

  1. 提示不以换行符结束,因此用户的响应会立即显示在其后面。标准I / O通常会同步标准输出和标准输入,以便刷新提示,尽管不以换行符结束。如果未显示提示,则可以在每个提示fflush(stdout);语句后添加fflush(0);printf()

  2. 检查scanf()的结果以处理EOF。

  3. scanf()的格式包括一个领先的空间。这将在返回的字符之前跳过空格,因此您将获得非空白的非换行符。

  4. 原始条件action != 'i' || action != 'd'始终为真;你需要&&代替。

  5. Nitpick:改进错误信息的语法。

  6. 请注意,在循环之后,如果用户触发了EOF(键入 Control-D 或等效项),则操作可能不是id。如果您获得EOF(例如,用户使用/dev/null的标准输入运行程序),除了action的初始化之外,'\0'中没有确定性值。

答案 2 :(得分:0)

我在这里修改了你的代码:

#include <stdio.h>

    int main()
    {

      char action;

      printf("Please enter 'i' to work with integers or 'd' to work with decimals.\n\n");


      scanf("%c", &action);
       while (action != 'i' && action != 'd') // here the loop will stop if action is 'i' or 'd'
       {
         printf("You didn't entered the right command. Please try again (i/d)\n");
         scanf("\n%c", &action);// here to deal with '\n'
       }
     }