Linux下C关闭然后打开标准输入

标签 c linux terminal console

我在 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/

相关文章:

c - 如何将结构写入文件 C

c - 二进制浮点加法

linux - 如何更改 bmp 图像的几何形状

linux - 在 shell 脚本中复制一个变量 (Linux)

python - VSCode 终端不显示所有行

c - 为什么网卡的mac地址可以修改?

c - 接收到的缓冲区包含带有一些垃圾值的实际数据

linux - 为什么重定向 + 管道 ( 2>&1 |) 合并两个流而不是将 stderr 移动到 stdout?

linux - 在 Linux 中从文件中打印最小值和最大值

vim - 终端可以检测到<Shift-Enter>或<Control-Enter>吗?