【问题标题】:getchar() in C is completed without pressing EnterC 中的 getchar() 无需按 Enter 即可完成
【发布时间】:2015-02-04 19:52:03
【问题描述】:

从我的previous post 中,我了解到 getchar() 仅在我们按 Enter 时完成。让我们考虑一下这段代码:

#include<stdio.h>
main()
{
  getchar();
  getchar();
  getchar();
  getchar();
  getchar();


}

我预计它会像这样运行:我按一些 key1 然后按 Enter,然后按 key2 按 Enter,然后按 key3 和 Enter,然后按 key4 和 Enter,最后按 key5+Enter,程序现在应该终止。这不是实际发生的情况。发生的情况是这样的:我按了某个 key1 然后按 Enter,然后 key2 一个 Enter,然后 key3 和 Enter,程序最终终止!

  • 为什么最后两个 getchar() 不起作用?

我观察到的另一件奇怪的事情是,如果我这样做:key1,key2,key3,key4+Enter,那么程序就会终止。例如。如果我连续按 q,w,e 和 r 然后回车,程序就会终止。

  • 为什么不是所有的 getchar() 都要求输入?这是否意味着 getchar() 将任何其他键作为 Enter ?但是接下来是否将下一个键作为下一个 getchar() 的输入?

让我们考虑另一个代码:

#include<stdio.h>
main()
{

  int c=getchar();
  int d=getchar();
  int e=getchar();
  printf("2 getchar are remaining\n");
  int f=getchar();
  int g=getchar();
  printf(" c is %d, d is %d, e is %d, f is %d and g is %d",c,d,e,f,g);

} 

我输入:ABCDEFG 然后回车。 2 getchar are remaining 应该在我按下 C 或 D 后立即打印出来。但它最后打印出来,意味着所有 getchar()s 都同时执行——这很奇怪。

  • 程序不是逐行执行的吗? IE。在第三个 getchar 之后, printf() 应该可以工作。但是当所有的 getchar() 都被执行时,它终于可以工作了。

【问题讨论】:

  • 输入被缓冲,直到您按下 Enter 键后才能用于 getchar()。该密钥也被返回。非缓冲输入通常在 CRT 中可用,但不是标准的。

标签: c io getchar


【解决方案1】:

对于您的第一个问题,回车键是getchar 可以处理和返回的字符。因此,如果您键入两个字符并按 Enter,则必须调用 getchar 三次以清除输入缓冲区。请记住,getchar 不是从键盘中获取键,而是从输入缓冲区中获取。因此,如果您将五个字符推入输入缓冲区,例如abcdenter,你必须调用getchar 5 次才能得到所有这些,第一个在你点击 enter 之前不会返回。

这也解释了你的第二个问题。 getchar 调用按顺序执行,而不是同时执行,一旦 enter 被击中,但第一个调用直到那时才执行。

您可能想了解disabling input buffering

【讨论】:

  • 意思是当我连续写完ABCD字符后按回车,然后编译器才真正启动程序。它将前 4 个字符提供给前四个 getchar(),如果第 5 个字符输入,则将其提供给最后一个 getchar()。
  • 这个输入缓冲区是如何初始化的?当编译器看到第一个 getchar() 时,它会启动输入缓冲区。在我按下 Enter 之前,输入缓冲区一直在输入字符。
  • 输入缓冲区由操作系统/终端管理,而不是编译器。编译器不启动程序,编译器编译程序。操作系统开始执行程序,然后 getchar 变成,我猜,一个阻塞的系统调用,如果你想用谷歌搜索的话。
【解决方案2】:

程序不是逐行执行的吗? IE。在第三个 getchar 之后, printf() 应该可以工作。但是当所有的 getchar() 都被执行时,它终于可以工作了。

它是逐行执行的,但是 ENTER 键是 getchar() 的有效输入,因此它将读取其 ASCII 值。无法告诉您更多信息,因为此值因系统而异。

【讨论】:

    【解决方案3】:

    getchar() 在你按下回车后完成是不正确的。只要有要读取的字符,getchar() 就会完成。这种差异很重要:例如,如果您使用您的程序并将标准输入重定向到文件:

    $ hexdump -C abcd_file 
    00000000  61 62 63 64 65                                    |abcde|
    00000005
    
    $ ./in < abcd_file 
    $
    

    请注意,“abcd_file”是一个包含“abcde”的文件,没有换行符,您的程序在任何地方都不需要换行符即可完成。那是因为文件一直在提供字符,而不是等待换行符。

    另一方面,通用终端或终端仿真器具有称为“规范模式”的操作模式。规范模式意味着终端支持“命令行处理设施”并且在用户按下 ENTER 之前不会发出可用字符的信号。这就是不正确的“getchar() 等待 ENTER”故事的来源。您可以将终端退出规范模式,并查看它检索所有字符而无需按 Enter:

    $ stty -icanon; ./in; stty icanon
    ggggg$
    

    在这种情况下,没有回车的 5 个字符使程序完成。

    最后,getchar() 看起来提前返回的原因是它还返回了 ENTER 字符。所以 "a\nb\nc\n" 是 6 个字符,前 5 个由 getchar() 返回,第 6 个在程序结束后从终端队列中删除。键入“abcd\n”还意味着 getchar() 将立即可用于 5 次连续读取,因为终端队列中存储了 5 个字符。

    http://www.gnu.org/software/libc/manual/html_node/Noncanonical-Input.html#Noncanonical-Input

    【讨论】:

    • 我使用的是 windows-7 操作系统。如何暂时将我的终端退出规范模式?
    【解决方案4】:

    getchar() 逐个字符地获取每个输入字符。它不会等待按下回车键。运行下面给出的程序并检查输出以获得更好的图片。

     #include <stdio.h>
        int main( ) {
    
           int c;
           int i;
           printf( "Enter a value :");
           i = getchar();
           printf( "Enter a value :");
           c = getchar();
           printf( "\nYou entered: ");
           putchar( c );
           printf( "\nYou entered: ");
           putchar(i);
           return 0;
        }
    

    输出:(输入一个字符后按下 Enter 键)

    Enter a value :1
    Enter a value :
    You entered:
    
    You entered: 1
    Process returned 0 (0x0)   execution time : 3.183 s
    Press any key to continue.
    

    输出:(在按回车键之前给出的输入)

    Enter a value :12
    Enter a value :
    You entered: 2
    You entered: 1
    Process returned 0 (0x0)   execution time : 5.389 s
    Press any key to continue.
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2016-03-06
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多