【发布时间】:2015-01-23 02:39:58
【问题描述】:
这是一个循环,从stdin 重复获取两个字符并输出它们。
char buf[2];
while (1)
{
printf("give me two characters: ");
fflush(stdout);
read(0, buf, 2);
printf("|%c%c|\n", buf[0], buf[1]);
}
问题在于,当在终端上按下 ENTER 键时,会插入一个换行符并保留在 stdin 缓冲区中,并将在下次调用 read 时被抓取。理想情况下,我希望每次调用 read 时都有一个清晰的 stdin 缓冲区,没有留下任何以前的垃圾。你能推荐一个好的解决方案吗?
我尝试了各种库调用,例如fgets,但是它们遇到了同样的问题。我正在考虑使用fpurge 手动清除缓冲区,但有人告诉我这不是一个好的解决方案。
这里的问题是剩余的输入应该被视为垃圾,并被丢弃。但是,当我下次调用 read 时,我无法区分剩余输入和新输入。
感谢您的意见。
【问题讨论】:
-
如果您的输入来自文件或来自其他进程的管道怎么办?在这些非交互式情况下,“清除标准输入”没有多大意义......如果我是你,我会考虑将换行符视为我正在解析的输入的一部分,而不是试图将其从缓冲区中删除你要的。
-
我看不出
fgets有同样的问题。哦,你一定是这样做了char buf[2]; fgets(buf,2,stdin);是的,确实有同样的问题,但这不是如何使用fgets。 -
您想准确读取两个字符,并在键入第二个字符后立即返回读取?还是您想读取一行的前两个字符,然后删除该行的其余部分?或者是其他东西?您需要有明确的要求才能获得准确的解决方案。
-
@iharob 我明白你现在在说什么了。第二次调用 read 取出缓冲区中剩余的所有内容。
-
@Cocksure:如果你真的想读取两个字符(即,不等待用户按下回车键),你需要在 termios 设置中取消设置
ICANON标志,并将VMIN更改为 2。(或者您可以将其更改为 1 并一次读取一个字符,由于各种原因,这通常是一个更好的主意。)Michael Kerrisk 的“Linux 编程接口”中有示例代码,我推荐如果您想认真对待低级 Linux 编程(免责声明:作者是朋友)。代码在线:man7.org/tlpi/code/online/book/tty/test_tty_functions.c.html