如何在休眠10秒后读取stdin全部内容并终止程序?
解决方案
1. 读取直到EOF(标准实现方式)
原代码的核心问题是将getchar()的返回值存入char类型变量中,而EOF是int类型(值为-1),若char为无符号类型,会导致永远无法匹配EOF。修改后的代码如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> // sleep函数的头文件,部分系统需要引入 int main() { sleep(10); int c; // 改为int类型,才能正确接收EOF while ((c = getchar()) != EOF) { putchar(c); } printf("\nEverything has been read from stdin\n"); return 0; }
说明
- 终端输入场景:输入内容后按Ctrl+D(Unix/Linux/macOS)或Ctrl+Z(Windows)触发EOF,程序会终止并打印提示。
- 管道/文件重定向场景:比如
echo "c" | ./your_program,程序会自动读取完所有内容后收到EOF,直接终止。
2. 仅读取sleep期间输入的可用内容(不等待后续输入)
如果需求是sleep结束后,只读取当前stdin中已存在的内容、不等待用户继续输入,可通过非阻塞IO结合select实现:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/select.h> #include <fcntl.h> int main() { sleep(10); // 将stdin设置为非阻塞模式 int flags = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); fd_set read_fds; FD_ZERO(&read_fds); FD_SET(STDIN_FILENO, &read_fds); // 检查stdin是否有数据可读,超时设为0(不等待) struct timeval timeout = {0, 0}; int ret = select(STDIN_FILENO + 1, &read_fds, NULL, NULL, &timeout); if (ret > 0 && FD_ISSET(STDIN_FILENO, &read_fds)) { int c; while ((c = getchar()) != EOF) { putchar(c); } } printf("\nEverything has been read from stdin\n"); return 0; }
说明
这种方式下,sleep结束后会立即检查stdin是否有输入数据,读取所有可用内容后直接终止,不会等待用户后续输入,适合一次性读取sleep期间输入内容的场景。
之前尝试失败的原因
- 检查EOF无效:用
char类型存储getchar()返回值,EOF是int类型的-1,当char为无符号时,-1会被转换为255,永远无法匹配EOF。 - stat函数无效:stdin是终端或管道这类字符设备时,
stat的st_size字段无实际意义,因为设备内容是动态生成的,没有预定义大小。
内容的提问来源于stack exchange,提问作者gurkensaas
相关产品推荐
相关产品推荐

