【问题标题】:How is the "getchar()" function able to take multiple characters as input?“getchar()”函数如何能够将多个字符作为输入?
【发布时间】:2016-05-08 13:08:08
【问题描述】:

这是一个基本的 C 字符计数程序:

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

int main(){
    long nc = 0;

    while(getchar() != EOF)
        nc++;
    printf("%ld\n" , nc);
}

当我输入“abcde”作为输入时,它显示值 6(触发 EOF 测试后),换行符 +1。但我怀疑getchar(),顾名思义,只考虑了 1 个字符。但是当我自己输入“abcde”时,它仍然有效。为什么会这样?我在这里有什么问题?

【问题讨论】:

  • 每次循环只读取一个字符。 nd 计算此类通过的次数。我不明白为什么你会认为它很神秘。
  • 去掉循环再看看!

标签: c


【解决方案1】:

默认情况下,标准输入通过交互式设备进行行缓冲。这意味着您的程序在准备好完整的行之前根本看不到任何输入,在您的情况下,当您点击 Enter 时。这样做的一个很好的原因是,如果用户输入她的 8 个字符的密码,然后按退格键 8 次,然后输入她的用户名并按 Enter,那么您的程序只会获取她的用户名,并且永远不会看到更正,这通常是您想要的,当您的外壳有机会在您将输入发送到任何地方之前编辑您的输入时。

所以发生的事情本质上是这样的:

  1. 你打电话给getchar()。没有可用的输入,因此等待。

  2. 您按下 a。这不是行尾,因此不会向您的程序发送任何输入,getchar() 没有可读取的内容,因此它仍在等待。

  3. 您按 b。这不是行尾,因此不会向您的程序发送任何输入,getchar() 没有可读取的内容,因此它仍在等待。

  4. 您按 c。这不是行尾,因此不会向您的程序发送任何输入,getchar() 没有可读取的内容,因此它仍在等待。

  5. 您按 d。这不是行尾,因此不会向您的程序发送任何输入,getchar() 没有可读取的内容,因此它仍在等待。

  6. 您按 e。这不是行尾,因此不会向您的程序发送任何输入,getchar() 没有可读取的内容,因此它仍在等待。

  7. 您按 Enter。现在它一行的结尾,所以输入"abcde\n" 被发送到你的程序。

  8. getchar() 现在有输入要读取,因此它返回'a',递增nc,然后循环返回以等待输入。

  9. 立即,getchar() 有更多输入要从该行中的其余字符中读取,因此它返回 'b',递增 nc,然后循环返回以等待输入。

  10. 立即,getchar() 有更多输入要从该行中的其余字符中读取,因此它返回 'c',递增 nc,然后循环返回以等待输入。

  11. 立即,getchar() 有更多输入要从该行中的其余字符中读取,因此它返回 'd',递增 nc,然后循环返回以等待输入。

  12. 立即,getchar() 有更多输入要从该行的其余字符中读取,因此它返回 'e',递增 nc,然后循环返回以等待输入。

  13. 立即,getchar() 有更多输入要从该行中的其余字符中读取,因此它返回 '\n',递增 nc,然后循环返回以等待输入。

  14. 如果您表示输入结束,也许通过按 Control-D,那么 getchar() 没有什么可读取的并且知道永远不会有任何要阅读的内容,因此它返回 EOF 并且您的循环结束。如果它不是输入结束,那么getchar() 将再次在这里等待您输入新的输入行。

所以这里实际发生的是getchar() 在您点击 Enter 之前什么也没做。然后,可能在您将手指从 Enter 键上移开之前,它运行了六次并消耗了您输入的六个字符。但是尽管getchar() 运行了六次, 只被提示输入一次(两次,如果你包括必须键入 Control-D ),因为getchar() 只会在没有可用输入并等待时等待您的输入。

在独立终端很普遍的日子里,实际的终端设备甚至可能直到一行结束才将任何字符传输到计算机,并且可能有少量的板载内存来允许这种类型的本地基于行的编辑,因此计算机本身可能直到行尾才真正看到它。在许多人使用的现代 PC 上,操作系统,在终端驱动程序级别,更可能会缓冲这些字符本身,并一次将它们呈现并让它们对您的程序可用(除非您特别告诉它你需要立即使用字符,当然)。

【讨论】:

    【解决方案2】:

    当您输入abcde\n(由Enter生成的\n)时,它会被刷新到标准输入流(stdin)中。

    getchar(),顾名思义,只考虑 1 个字符

    是的,没错。但请注意,getchar 用于 loop 循环,直到getchar 返回EOF。另外,请记住 getcharstdin 读取输入。

    因此,在第一次迭代中,在您输入数据后,getchar 会读取第一个字符 a。在第二次迭代中,它不等待输入,因为stdin 仍然包含bcde\n,因此读取下一个字符b 等等。

    最后,当您触发EOF 时,循环中断。然后,printf 被执行(打印6,因为读取了六个字符),程序结束。

    【讨论】:

    • 好的,但是每次调用getchar,都得输入一些东西。如果bcde\n 仍然存在于stdin 中,为什么会发生这种情况
    • getchar 等待输入 如果 stdin 为空。否则,它不会并消耗下一个字符。
    【解决方案3】:

    getchar 从标准输入的缓冲区中读取下一个字符并将其返回,因为您将六个字符 - “abcde\n” - 输入到标准输入中,并且您在 while 循环中调用 getchar,这意味着循环体运行了六次,它一一读取字符。您可以通过以下方式进行测试:

    int c;
    while ((c = getchar()) != EOF) {
        printf("got %c\n", c);
        nc++;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 2019-03-20
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多