【问题标题】:Why doesn't getchar() wait for me to press enter after scanf()?为什么 getchar() 不等我在 scanf() 之后按回车?
【发布时间】:2010-11-26 08:48:23
【问题描述】:

我正在学习 C,我正在使用“getchar()”来停止命令窗口,这样我就可以看到正在做的练习,但它不起作用。这是一个示例:

#include <stdio.h>

int main()
{
    int value;
    printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: ");
    scanf("%d", &value);
    switch (value)
    {
        case 1:
            printf("you selected the option 1.");
            break;
        case 2:
            printf("you selected the option 2.");
            break;
        case 3:
            printf("you selected the option 3.");
            break;
        case 4:
            printf("goodbye");
            break;
        default:
            printf("thats not an option");
            break;
    }
    getchar();
    return 0;
}

这是输出:

  1. 选项 1。
  2. 选项 2。
  3. 选项 3。
  4. 退出。

做一个选项:1

您选择了选项 1。

进程返回 0 (0x0) 执行时间:3.453 s

按任意键继续。

为什么不等待“getchar()”的输入?

【问题讨论】:

标签: c getchar


【解决方案1】:

您的 scanf 只吃掉了数字,但没有吃掉尾随的换行符。在 %d 之后放置一个换行符或空格将给你带来相反的问题,读得太远。

这就是人们不喜欢 scanf 的原因。

我建议阅读实际的一行(使用fgets(3)),然后使用sscanf() 扫描字符串。

【讨论】:

    【解决方案2】:

    首先,不要使用 fflush() 来清除输入流;行为未定义:

    7.19.5.2.2 如果流指向输出流或更新流,其中最近的 未输入操作,fflush 函数会导致该流的任何未写入数据 被交付到宿主环境中写入文件;否则,行为是 未定义。

    问题是尾随换行符没有被“%d”转换说明符使用,所以它被getchar() 立即拾取。没有一种最好的方法来处理这个问题,但通常方法是将整行作为文本读取(使用 fgets()scanf() 以及大小为“%s”的转换说明符),这将消耗换行符,然后使用sscanf()strtol()strtod() 转换为目标数据类型。

    【讨论】:

      【解决方案3】:

      getchar 可以获取您在 1 之后输入的回车吗?

      【讨论】:

      • 是的,getchar() 正在获取终止输入的换行符,因此它不会等待很长时间,因为数据已经在其缓冲区中。
      • 见鬼,如果那是错误的。我喜欢 fflush 答案并尝试一下。
      • 但这是未定义的行为,可能不可移植,尤其不推荐用于家庭作业式的学习体验。遵循已发布和标准化的 API! :-)
      【解决方案4】:

      getchar() 正在 scanf 中从键盘读取 \n - 请参阅 here 了解更多信息

      【讨论】:

        【解决方案5】:

        你得到一个回车,我会绕过它,定义一个字符,然后让它扫描回车,

        char ch; (在您的 getch() 之前输入以下内容) scanf("%c",&ch); getchar();

        应该以这种方式工作,不是最有效的方式,但对我有用。

        【讨论】:

          【解决方案6】:

          如前所述,scanf 在读取用户输入后会留下 \n。

          解决方案: 在 scanf 之后直接添加 getchar()。

          这弥补了 scanf 的不足。

          int value; 
          printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: "); 
          scanf("%d", &value);
          getchar();
          switch (value) 
          

          【讨论】:

            【解决方案7】:

            我认为您在输入“1”后输入了回车。它将被getchar() 接受。因此,您只需在原来的getchar() 之后(就在return 0; 之前)添加一个额外的getchar() 即可解决问题。

            ** 我对此进行了测试,它确实有效。

            【讨论】:

              【解决方案8】:

              在阅读其他答案时,我突然想到您可以使用scanf("%d\n",&amp;n); 而不是 scanf("%d",&amp;n); 从缓冲区中删除新行。我还没有检查过这个。

              希望它有效:D

              【讨论】:

              • 我认为这不适用于递归函数,但应该适用于循环。 “你不能取悦所有人”
              • 这不会按预期工作。由于格式字符串中的\nscanf 不会返回,直到您输入任何数字之后输入非空白字符。
              【解决方案9】:
              #include <stdio.h> 
              #include<conio.h>
              void main() 
              { 
                  int value; 
                  printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: "); 
                  scanf("%d", &value); 
                  switch (value) 
                  { 
                      case 1: 
                          printf("you selected the option 1."); 
                          break; 
                      case 2: 
                          printf("you selected the option 2."); 
                          break; 
                      case 3: 
                          printf("you selected the option 3."); 
                          break; 
                      case 4: 
                          printf("goodbye"); 
                          break; 
                      default: 
                          printf("thats not an option"); 
                          break; 
                  } 
                  getch(); 
              } 
              

              【讨论】:

              • 那么,您的答案是改用getch 吗?你能否说得更清楚(如果确实如此)?
              【解决方案10】:

              为了让您的程序正常工作,您应该在调用 getchar() 之前“刷新”输入流并调用 fflush(stdin)。这样做的目的是,当您在键盘上输入一个数字然后按回车键时,输入缓冲区会同时获取两个字符,例如“1”和“\n”,而您对 scanf 的调用只会得到“1”,因此“ \n' 保留在输入缓冲区中。当你调用 getchar 时,你正在“gettin”剩下的 '\n'。刷新输入会丢弃所有缓冲区。

              【讨论】:

              • fflush(stdin)未定义的行为。不要这样做。
              • 那我该怎么做呢?我对此真的很陌生,我来自 python 作为我的第一门编程语言,所以关于内存管理的一切对我来说都是中文的..
              • 哇..我不知道..只是做了一些研究,发现了这个解释gidnetwork.com/b-57.html
              • stackoverflow.com/questions/1384073/… 中查看我的答案或接受的答案。它归结为 a) 使用 fgets 读取整行,然后使用 sscanf 解析它或 b) 放入第二个 getchar 以“吃掉”换行符。
              • 很抱歉对fflush(stdin) 太苛刻了,但它确实是其中一件事,它看起来应该可以工作,直到它导致你无法追踪的讨厌的错误。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多