getch
和getchar
函数之间的确切区别是什么?
getchar()
是一个标准函数,它从stdin中获取一个字符。
getch()
不合标准。它从键盘获取一个字符(可能与stdin不同)并且不回显它。
标准C函数是getchar()
,在<stdio.h>
中声明。它从一开始就基本存在。它从标准输入(stdin
)读取一个字符,它通常是用户的键盘,除非它已被重定向(例如通过shell输入重定向字符<
或管道)。
getch()
和getche()
是旧的MS-DOS函数,在<conio.h>
中声明,并且仍然在Windows系统上很流行。它们不是标准C功能;它们并不存在于所有系统中。 getch
立即从键盘上读取一次击键,无需等待用户点击Return键,也无需回显按键。 getche
是相同的,除了它确实回声。据我所知,getch
和getche
总是从键盘上读取;它们不受输入重定向的影响。
问题自然会出现,如果getchar
是标准函数,你如何使用它来读取一个字符而不等待Return键,或者没有回应?这些问题的答案至少有点复杂。 (事实上,它们很复杂,我怀疑它们解释了getch
和getche
的持久受欢迎程度,如果没有其他任何东西都很容易使用。)
答案是getchar
无法控制回声和输入缓冲等细节 - 就C而言,这些是较低级别的系统相关问题。
但是理解getchar
假设的基本输入模型是有用的。令人困惑的是,通常有两种不同级别的缓冲。
getchar
只是从该缓冲区中获取下一个字符。当缓冲区为空时,stdio包会尝试通过从操作系统中读取更多字符来重新填充它。所以,如果我们跟踪一个程序第一次调用getchar
时发生的事情:stdio发现它的输入缓冲区是空的,所以它试图从操作系统中读取一些字符,但是还没有任何可用的字符,所以read
呼叫阻止。同时,用户可能正在键入一些字符,这些字符在终端驱动程序的输入缓冲区中累积,但是用户还没有点击Return。最后,用户点击Return,并且阻塞的read
调用返回,将整行的字符值返回给stdio
,后者使用它们填充其输入缓冲区,然后将其返回第一个到getchar
的初始调用。一直耐心等待。 (然后如果程序第二次或第三次调用getchar
,可能会有更多的字符 - 用户键入的行上的下一个字符 - 在stdio的输入缓冲区中可用于getchar
立即返回。有关此内容的更多内容,请参阅这些section 6.2的C course notes。)
但是在所有这些中,正如您所看到的,getchar
和stdio包无法控制回显或输入行编辑等细节,因为在步骤1中,它们在较低级别的终端驱动程序中处理得较早。
因此,至少在类Unix操作系统下,如果要在不等待返回键的情况下读取字符,或者控制是否回显字符,可以通过调整终端驱动程序的行为来实现。细节有所不同,但有一种方法可以打开和关闭回声,以及一种打开和关闭输入行编辑的方式(实际上有两种方式)。 (至少有一些细节,请参阅旧this SO question中的question 19.1或C FAQ list。)
当关闭输入行编辑时,操作系统可以立即返回字符(无需等待返回键),因为在这种情况下,它不必担心用户可能输入了需要“取消”的错误按键“使用Delete或Backspace键返回”。 (但同样的道理,当一个程序关闭终端驱动程序中的输入行编辑时,如果它想让用户纠正错误,它必须实现自己的编辑,因为它会看到---也就是说,连续对getchar
的调用将返回 - 用户的错误字符和Delete或Backspace键的字符代码。)
getch()
它只是得到一个输入,但从来没有在屏幕上显示它作为输出,尽管我们按下回车键。
当我们按下回车键时,getchar()
会得到一个输入并在屏幕上显示它。
getchar
是标准C,在stdio.h中找到。它从stdin
读取一个字符(标准输入流=大多数系统上的控制台输入)。这是一个阻塞调用,因为它要求用户键入一个字符然后按Enter键。它回应用户对屏幕的输入。getc(stdin)
100%相当于getchar
,但它也可用于其他输入流。getch
是非标准的,通常在旧的过时MS DOS头文件conio.h中找到。它的工作原理就像getchar
,除了它在第一次击键后没有阻塞,它允许程序继续而无需用户按下回车键。它不会将输入回显到屏幕。getche
与getch
相同,也是非标准的,但它与屏幕的输入相呼应。