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

问题描述 投票:17回答:4

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

c io console-application stdio c-standard-library
4个回答
28
投票

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

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


3
投票

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

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

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

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

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

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

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

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

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

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


1
投票

getch()它只是得到一个输入,但从来没有在屏幕上显示它作为输出,尽管我们按下回车键。

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


0
投票
  • getchar是标准C,在stdio.h中找到。它从stdin读取一个字符(标准输入流=大多数系统上的控制台输入)。这是一个阻塞调用,因为它要求用户键入一个字符然后按Enter键。它回应用户对屏幕的输入。
  • getc(stdin) 100%相当于getchar,但它也可用于其他输入流。
  • getch是非标准的,通常在旧的过时MS DOS头文件conio.h中找到。它的工作原理就像getchar,除了它在第一次击键后没有阻塞,它允许程序继续而无需用户按下回车键。它不会将输入回显到屏幕。
  • getchegetch相同,也是非标准的,但它与屏幕的输入相呼应。
© www.soinside.com 2019 - 2024. All rights reserved.