getch()和getchar()有什么区别?

getchgetchar函数之间的确切区别是什么?

getchar()是一个从stdin获取字符的标准函数。

getch()是非标准的。 它从键盘获取一个字符(可能与stdin不同)并且不回显它。

标准C函数是getchar() ,在声明。 它基本上从一开始就存在。 它从标准输入( stdin )读取一个字符,通常是用户的键盘,除非它已被重定向(例如通过shell输入重定向字符<或管道)。

getch()getche()是旧的MS-DOS函数,在声明,在Windows系统上仍然很流行。 它们不是标准Cfunction; 它们并不存在于所有系统中。 getch立即从键盘上读取一次击键,无需等待用户点击Return键,也无需回显键击。 getche是相同的,除了它确实回声。 据我所知, getchgetche 总是从键盘上读取; 它们不受输入重定向的影响。

问题自然会出现,如果getchar是标准函数,你如何使用它来读取一个字符而不等待Return键,或者没有回显? 这些问题的答案至少有点复杂。 (事实上​​,它们足够复杂,我怀疑它们解释了getchgetche的持久流行,如果没有其它的东西都很容易使用。)

答案是getchar无法控制回声和输入缓冲等细节 - 就C而言,这些是较低级别的系统相关问题。

但是理解getchar假设的基本输入模型是有用的。 令人困惑的是,通常有两种不同级别的缓冲。

  1. 当用户键入键盘上的键时,它们由操作系统的终端驱动程序读取。 通常,在默认模式下,终端驱动程序会在键入时立即回显键击(因此用户可以看到他们正在键入的内容)。 通常,在默认模式下,终端驱动程序还支持一定量的行编辑 - 例如,用户可以按Delete或Backspace键删除意外类型的字符。 为了支持行编辑,终端驱动程序通常在输入缓冲区中收集字符。 只有当用户点击Return时,该缓冲区的内容才可供调用程序使用。 (仅当标准输入实际上是键盘或其他串行设备时,才会出现此级别的缓冲。如果标准输入已重定向到文件或管道,则终端驱动程序不起作用,并且此级别的缓冲不适用。)

  2. stdio包将操作系统中的字符读入其自己的输入缓冲区。 getchar只是从该缓冲区中获取下一个字符。 当缓冲区为空时,stdio包会尝试通过从操作系统中读取更多字符来重新填充它。

因此,如果我们跟踪程序第一次调用getchar时发生的事情:stdio发现它的输入缓冲区是空的,所以它尝试从操作系统中读取一些字符,但是还没有任何字符可用,所以read调用块。 同时,用户可能正在键入一些字符,这些字符正在终端驱动程序的输入缓冲区中累积,但是用户还没有点击Return。 最后,用户点击Return,并且阻塞的read调用返回,将整行的字符值返回给stdiostdio使用它们填充其输入缓冲区,然后从第一个返回到getchar初始调用,一直耐心等待。 (然后如果程序第二次或第三次调用getchar ,可能会有更多的字符 - 用户键入的行上的下一个字符 - 在stdio的输入缓冲区中可用,以便getchar立即返回。有关此内容的更多内容,参见这些C课程笔记的 第6.2节 。)

但是在所有这些中,正如您所看到的, getchar和stdio包无法控制回显或输入行编辑等细节,因为在步骤1中,它们在较低级别处理,在终端驱动程序中处理。

因此,至少在类Unix操作系统下,如果要在不等待返回键的情况下读取字符,或者控制是否回显字符,可以通过调整终端驱动程序的行为来实现。 细节有所不同,但有一种方法可以打开和关闭回声,以及一种打开和关闭输入行编辑的方式(实际上有两种方式)。 (至少有一些细节,请参阅旧的问题 ,或旧的C FAQ列表中的问题19.1 。)

当关闭输入行编辑时,操作系统可以立即返回字符(无需等待返回键),因为在这种情况下,它不必担心用户可能输入了需要“取消”的错误按键“使用Delete或Backspace键返回”。 (但出于同样的原因,当一个程序关闭终端驱动程序中的输入行编辑时,如果它想让用户纠正错误,它必须实现自己的编辑,因为它会看到---也就是说,连续对getchar调用将返回 - 用户的错误字符 Delete或Backspace键的字符代码。)

getch()它只是获取一个输入但是从不在屏幕上显示它作为输出,尽管我们按下了回车键。

getchar()当我们按下回车键时,它会获得一个输入并在屏幕上显示它。

  • getchar是标准的C,可以在stdio.h中找到。 它从stdin读取一个字符(标准输入流=大多数系统上的控制台输入)。 这是一个阻塞调用,因为它要求用户键入一个字符,然后按Enter键。 它回应用户对屏幕的输入。

  • getc(stdin)getchar等效,除了它也可以用于其他输入流。

  • getch是非标准的,通常在旧的过时MS DOS头文件conio.h中找到。 它就像getchar一样工作,除了它在第一次击键后没有阻塞,它允许程序继续而无需用户按下回车键。 它不会将输入回显到屏幕。

  • getchegetch相同,也是非标准的,但它会将输入回显到屏幕上。