我在 Linux (Raspbian - Raspberry Pi) 下有一个 C 控制台应用程序。该程序有一些字符动画 - 它逐个字符地打印出消息。例如,文本
Please give me your name!
5 秒后完全打印出来(逐个字符)。
之后,系统会要求用户输入他们的姓名,如果用户等待消息被打印出来,这会很好地工作。但是,如果用户不耐烦,随意敲击键盘上的按键,会影响后面的输入请求。
假设用户输入
abc\nefgh\n
当上面的文本被回显时('\n' 表示换行 - 输入)。如果发生这种情况,将不会要求用户正确输入他/她的姓名,但字符数组“abc”将被接受为输入并得到验证。
我的问题是如何暂时禁用输入(缓冲)(在 Linux 上)。我尝试了几种方法并阅读了很多关于这样做的帖子,但没有一个对我的目的有用。
负责请求输入的函数如下:
int getLine(char *s, int length)
{
int i;
char c;
for (i = 0; i < length && (c = getchar()) != EOF && c != '\n'; i++)
{
if (c == '\0')
{
i--;
}
else
{
s[i] = c;
}
}
s[i] = '\0';
while (c != EOF && c != '\n')
{
c = getchar();
}
return i;
}
空行在调用上述函数的 while 循环的帮助下被消除,因此 enter 输入被认为是无效的。
我尝试关闭标准输入,但无法重新打开它:
fclose(stdin);
并在 getLine
之前清空缓冲区:
char buf[BUFSIZ];
while (c = fgets(buf, BUFSIZ, stdin) != NULL);
不幸的是,它无法像处理文本文件那样工作。
fflush(stdin);
也没有用,反正也不漂亮。
我的目标是防止用户在写出文本时输入任何内容,并暂时忽略/关闭输入缓冲 (stdin)。此外,在 Linux 终端上显示时,最好在打印期间禁用输出(刷新)用户输入。
最佳答案
您可以通过直接与 TTY 交互来完成此操作。查看 passwd
或类似实用程序的源代码以获取灵感。
下面的函数清除 TTY 输入缓冲区(省略错误处理)。您需要在读取用户输入之前调用它。
#include <sys/ioctl.h>
#include <termios.h>
void clear_user_input() {
if (isatty(STDIN_FILENO)) {
int fd = open(ttyname(STDIN_FILENO), O_RDONLY);
ioctl(fd, TCFLSH, TCIFLUSH);
close(fd);
}
}
关于Linux下C关闭然后打开标准输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38329044/