简体   繁体   English

是什么让fgets()实际上等待用户输入,如果指向stdin?

[英]What makes fgets() actually wait for user input if pointed to stdin?

I am new to C, and I am trying to understand what goes on in fgets() when pointed to stdin . 我是C的新手,我试图理解当指向stdinfgets()发生了什么。

Basically my question is this, forgive me I might not actually understand fgets() that well: 基本上我的问题是这个,请原谅我,我可能实际上并不理解fgets()

If I specify a pointer to some file to use in fgets() , then fgets() reads from that location onwards up to either \\n , EOF , or the specified limit-1 如果我指定一个指向某个文件的指针以在fgets() ,那么fgets()从该位置开始向上读取,直到\\nEOF或指定的limit-1

So why does it behave differently if I point to stdin , in the sense, what makes it wait for user input rather than simply finding nothing to read and hence returning NULL ? 那么,为什么我指向stdin ,从某种意义上来说,它是什么让它等待用户输入而不是简单地找不到任何东西来读取因此返回NULL

Thank you for your time 感谢您的时间

fgets() reads from the argument stream. fgets()从参数流中读取。 If this stream is tied to a device or a pipe, it blocks until input is obtained from the device/pipe or until an end of file is detected. 如果此流绑定到设备或管道,它将阻塞,直到从设备/管道获取输入或直到检测到文件末尾。

stdin is usually tied to the terminal. stdin通常与终端绑在一起。 Reading from the terminal reads any pending input and in the case of fgets() keeps reading until a newline is typed or enough characters are input. 从终端读取读取任何挂起的输入,并且在fgets()的情况下保持读取,直到键入换行符或输入足够的字符。 There is one extra layer to understand here: the kernel driver for the terminal performs its own buffering by default, causing the input operation to block until a newline is typed even if more characters are typed than fgets() expects. 这里有一个额外的层要理解:终端的内核驱动程序默认执行自己的缓冲,导致输入操作阻塞,直到输入换行符,即使键入的字符数多于fgets()字符数。 These extra characters are left pending in the terminal buffer. 这些额外字符在终端缓冲区中保留未决状态。

The terminal can be configured for raw mode (as opposed to the default cooked mode) with the stty system call (on Posix systems). 可以使用stty系统调用(在Posix系统上)将终端配置为原始模式(与默认的模式相对)。 Doing this would remove the buffering in the device driver, but buffering would still be performed in the FILE * stream. 这样做会删除设备驱动程序中的缓冲,但仍会在FILE *流中执行缓冲。 fgets() can only access characters from the stream after this buffering is performed. fgets()只能在执行此缓冲后访问流中的字符。 Streams tied to devices are usually line buffered by default, causing the stream buffering to match the device drive buffering. 绑定到设备的流通常默认为行缓冲,导致流缓冲与设备驱动器缓冲匹配。 If you set both the device to raw mode and the stream as unbuffered, characters will be available to fgets() as they are typed and fgets() will stop reading when it gets a newline or when it has read size-1 characters. 如果同时设置设备以原始模式和流作为缓冲,人物将可fgets()因为它们是输入和fgets()就会停止阅读时,它得到一个新行或当它读取size-1个字符。

Note also that you can enter an end of file in cooked mode by typing Control-D on unix and OS/X systems and Control-Z Enter on Windows systems. 还要注意的是,你可以在UNIX和OS / X系统和控制-Z输入在Windows系统上输入控制-d熟模式下输入文件的末尾。

If I specify a pointer to some file to use in fgets(), then fgets() reads from that location onwards up to either \\n, EOF, or the specified limit-1 如果我指定一个指向某个文件的指针以在fgets()中使用,那么fgets()从该位置开始向上读取,直到\\ n,EOF或指定的限制-1

It doesn't read from that location , it reads from that file . 它不从该位置读取,它从该文件中读取。

So why does it behave differently if I point to stdin, in the sense, what makes it wait for user input rather than simply finding nothing to read and hence returning NULL? 那么,为什么我指向stdin,从某种意义上来说,它是什么让它等待用户输入而不是简单地找不到任何东西来读取因此返回NULL?

It doesn't behave any differently. 它的行为没有任何不同。 The fgets function only accepts a pointer to a file and it always reads from that file. fgets函数接受指向文件的指针,它总是从该文件中读取。

I suspect you're confusing fgets with some other function that does something else. 我怀疑你将fgets与其他一些其他功能相混淆。 The fgets function is, and only is, a function to do a blocking read from a file. fgets函数是,也是唯一一个从文件执行阻塞读取的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM