使用 fgets() 检测 EOF,其中 filesteam 是标准输入

Detecting EOF with fgets() where filesteam is stdin

一些背景,我正在编写一个玩游戏的程序 "boxes" 它在 linux 命令行中运行并用 C 编写。有一个等待用户输入的提示,然后使用 fgets() 读取并解释等

作为任务规范的一部分,如果我达到 "End of file while waiting for user input",我必须 return 一个特定的错误。我知道 fgets() return 在到达 EOF 时为空...但是说我有

fgets(input,max_buffer,stdin);

在提示循环中,如果用户使用 CTRL+C 或 CTRL+D 提前退出,这是否意味着输入 == NULL?

我什至可以检测到用户何时使用 fgets 执行此操作吗?

我只是想解决这个问题,在此先感谢您的帮助。

(OS: UNIX) (编译器:gcc - c90)

当最终用户使用 Ctrl+C 永久退出时,您的程序会立即失去控制,这意味着您不会从 fgets 获得任何进一步的输入,甚至不会是 NULL。

另一方面,Ctrl+D 会在不关闭程序的情况下关闭输入流,因此您会从 fgets 调用中得到 NULL 结果。

您可以将程序设置为通过处理信号来处理 Ctrl+C,但这种处理会发生在输入循环之外。

来自 herefgets

Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.

A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.

A terminating null character is automatically appended after the characters copied to str.

因此,当用户输入 CTRL-D(文件结束)时,fgets 将 return,当 \n(换行符)遇到。 CTRL-C 将 默认 完全终止您的程序。

如果您想抓住 CTRL-C 并优雅地退出,您可以:

#include <signal.h>

void intHandler(int dummy) {
    //graceful CTRL-C exit code.
}

int main(void) {
    signal(SIGINT, intHandler);
    //your code
}
    

文档 (C99 §7.19.7.2):

The fgets function returns s if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned.

因此,如果出现文件结尾,但已读取字符,fgets 将不会 return NULL。如果在读取任何输入之前发生 EOF,它将 return NULL.

您可以使用 feof and ferror 函数区分 EOF 和读取错误。