`getchar()` returns 错误的特殊情况是什么?
What are the particular cases `getchar()` returns error?
所以我知道 getchar()
returns EOF 当输入结束或发生错误时。我也知道我可以检查 ferror(stdin)
和 feof(stdin)
发生了哪些情况。
我想知道特别是在什么情况下会出现错误。
我查看了这两个函数的手册页,但那里什么也没有。
所有 stdio.h 都指向一个叫做 错误指示器 的东西,它是一个内部变量,据说位于应用程序程序员拥有的不透明 FILE
对象中无法访问(参见 C17 7.21.1)。
getchar
的文档可在 C17 7.21.7.6 中找到:
The getchar function returns the next character from the input stream pointed to by
stdin. If the stream is at end-of-file, the end-of-file indicator for the stream is set and
getchar returns EOF. If a read error occurs, the error indicator for the stream is set and
getchar returns EOF.
所以我们不知道 getchar
返回 EOF
是因为它到达了流的末尾,还是因为存在读取错误。为了知道,我们必须检查错误指示器。
这就是 ferror(stdin)
的用武之地。它是一个稍微有用的函数,因为它只执行此操作 (C17 7.21.10.3):
The ferror function returns nonzero if and only if the error indicator is set for
stream.
仅此而已 - 这是一个标准化的、可移植的抽象层,我们无法真正了解幕后发生的事情。这很好,因为大多数时候我们根本不在乎。
在这些标准 C 函数下会有一个 OS-特定的 API,如果是 POSIX 可能 read()
,如果是 Windows 可能 ReadFile()
等。这些函数又可能因多种原因而失败:文件句柄不正确,文件被另一个进程占用,OS 授予用户的文件没有读取权限等等。
理论上 getchar
也可以连接到嵌入式系统上的串行总线,在这种情况下,失败的原因与托管系统上的原因完全不同。现在我们突然谈论错误的波特率、缓冲区溢出、帧错误或任何适用的问题。
getchar()
可以 return EOF
用于多个系统特定的 I/O 错误。 getchar()
被定义为等同于 getc(stdin)
,它本身等同于 fgetc(stdin)
,只是它可以作为宏来实现。以下是 linux man page 中 linux 系统的可能原因列表:
RETURN VALUE
Upon successful completion, fgetc()
shall return the next byte
from the input stream pointed to by stream. If the end-of-file
indicator for the stream is set, or if the stream is at end-of-
file, the end-of-file indicator for the stream shall be set and
fgetc()
shall return EOF
. If a read error occurs, the error
indicator for the stream shall be set, fgetc()
shall return EOF
,
and shall set errno
to indicate the error.
ERRORS
The fgetc()
function shall fail if data needs to be read and:
EAGAIN
The O_NONBLOCK
flag is set for the file descriptor
underlying stream and the thread would be delayed in the
fgetc()
operation.
EBADF
The file descriptor underlying stream is not a valid file
descriptor open for reading.
EINTR
The read operation was terminated due to the receipt of a
signal, and no data was transferred.
EIO
A physical I/O error has occurred, or the process is in a
background process group attempting to read from its
controlling terminal, and either the calling thread is
blocking SIGTTIN
or the process is ignoring SIGTTIN
or the
process group of the process is orphaned. This error may
also be generated for implementation-defined reasons.
EOVERFLOW
The file is a regular file and an attempt was made to read
at or beyond the offset maximum associated with the
corresponding stream.
The fgetc()
function may fail if:
ENOMEM
Insufficient storage space is available.
ENXIO
A request was made of a nonexistent device, or the request
was outside the capabilities of the device.
所以我知道 getchar()
returns EOF 当输入结束或发生错误时。我也知道我可以检查 ferror(stdin)
和 feof(stdin)
发生了哪些情况。
我想知道特别是在什么情况下会出现错误。
我查看了这两个函数的手册页,但那里什么也没有。
所有 stdio.h 都指向一个叫做 错误指示器 的东西,它是一个内部变量,据说位于应用程序程序员拥有的不透明 FILE
对象中无法访问(参见 C17 7.21.1)。
getchar
的文档可在 C17 7.21.7.6 中找到:
The getchar function returns the next character from the input stream pointed to by stdin. If the stream is at end-of-file, the end-of-file indicator for the stream is set and getchar returns EOF. If a read error occurs, the error indicator for the stream is set and getchar returns EOF.
所以我们不知道 getchar
返回 EOF
是因为它到达了流的末尾,还是因为存在读取错误。为了知道,我们必须检查错误指示器。
这就是 ferror(stdin)
的用武之地。它是一个稍微有用的函数,因为它只执行此操作 (C17 7.21.10.3):
The ferror function returns nonzero if and only if the error indicator is set for stream.
仅此而已 - 这是一个标准化的、可移植的抽象层,我们无法真正了解幕后发生的事情。这很好,因为大多数时候我们根本不在乎。
在这些标准 C 函数下会有一个 OS-特定的 API,如果是 POSIX 可能 read()
,如果是 Windows 可能 ReadFile()
等。这些函数又可能因多种原因而失败:文件句柄不正确,文件被另一个进程占用,OS 授予用户的文件没有读取权限等等。
理论上 getchar
也可以连接到嵌入式系统上的串行总线,在这种情况下,失败的原因与托管系统上的原因完全不同。现在我们突然谈论错误的波特率、缓冲区溢出、帧错误或任何适用的问题。
getchar()
可以 return EOF
用于多个系统特定的 I/O 错误。 getchar()
被定义为等同于 getc(stdin)
,它本身等同于 fgetc(stdin)
,只是它可以作为宏来实现。以下是 linux man page 中 linux 系统的可能原因列表:
RETURN VALUE
Upon successful completion,
fgetc()
shall return the next byte from the input stream pointed to by stream. If the end-of-file indicator for the stream is set, or if the stream is at end-of- file, the end-of-file indicator for the stream shall be set andfgetc()
shall returnEOF
. If a read error occurs, the error indicator for the stream shall be set,fgetc()
shall returnEOF
, and shall seterrno
to indicate the error.ERRORS
The
fgetc()
function shall fail if data needs to be read and:
EAGAIN
TheO_NONBLOCK
flag is set for the file descriptor underlying stream and the thread would be delayed in thefgetc()
operation.
EBADF
The file descriptor underlying stream is not a valid file descriptor open for reading.
EINTR
The read operation was terminated due to the receipt of a signal, and no data was transferred.
EIO
A physical I/O error has occurred, or the process is in a background process group attempting to read from its controlling terminal, and either the calling thread is blockingSIGTTIN
or the process is ignoringSIGTTIN
or the process group of the process is orphaned. This error may also be generated for implementation-defined reasons.
EOVERFLOW
The file is a regular file and an attempt was made to read at or beyond the offset maximum associated with the corresponding stream.The
fgetc()
function may fail if:
ENOMEM
Insufficient storage space is available.
ENXIO
A request was made of a nonexistent device, or the request was outside the capabilities of the device.