C程序中的非规范终端模式缓冲区标准输出

暴风雨

我正在做一个学校项目(构建一个非常基本的外壳)。

想法是能够像在bash中一样进行行编辑。为此,我将终端模式更改为非规范,然后停止回显。

我编写了一个非常简单的代码来揭露我的问题(请注意,我确实检查了函数的返回等...在本文中,我将其做得尽可能短)

#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    int     ret;
    char    buff;
    char    *term_name;
    char    *termcap;
    struct termios  termios_new;
    struct termios  termios_backup;

    /*
    ** Init termcap library
    */
    term_name = getenv("TERM");
    tgetent(NULL, term_name);

    /*
    ** Get the terminal mode to non canonical and shut down echo
    */
    bzero(&termios_new, sizeof(struct termios));
    tcgetattr(STDIN_FILENO, &termios_backup);
    termios_new = termios_backup;

    termios_new.c_lflag &= ~(ICANON);
    termios_new.c_lflag &= ~(ECHO);
    termios_new.c_cc[VMIN] = 1;
    termios_new.c_cc[VTIME] = 0;

    /*
    **  Set the change
    */
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios_new);

    /*
    ** Get the termcap for clearing screen on the particular terminal
    */
    termcap = tgetstr("cl", NULL);

    /*
    ** Loop read to get user entries and clear screen for 'c', output char for 'b', break for 'q'
    */
    while((ret = read(STDIN_FILENO, &buff, 1)) > 0)
    {
        if (buff == 'c')
            tputs(termcap, 1, putchar);
        else if (buff == 'b')
            putchar(buff);
        else if (buff == 'q')
            break ;
        buff = 0;
    }

    /*
    ** Put back the terminal mode as found before
    */
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios_backup);
    return (0);
}

因此,基本上,这是读取用户的条目的循环。它将清除“ c”的屏幕,输出“ b”的字符,中断并恢复“ q”的原始终端模式。

问题是:

每当我键入任何内容时,它似乎都会被缓冲,因为直到我用'q'中断循环之前,什么都不会发生。这时,输出显示在屏幕上,如果我键入5次b,则得到5个b,如果键入“ c”,则屏幕将被清除。但是,仅在键入“ q”之后。恢复或不恢复原始终端模式时的行为相同。(的最后一行return

我怀疑:

在使代码非常简短并检查所有返回值之后,我倾向于认为更改终端模式的方式只会出现问题?我尝试使用标志TCSAFLUSH具有相同结果TCSADRAINtcsetattr功能。

谢谢 !:)

暴风雨

✅已解决:

好吧,对于遇到这种情况的任何人,这都很有趣,因为它使我学到了很多东西(这是一个学校项目,所以……)。

putchartputs参数中使用是个问题,因为putchar被缓冲,就像printf一样。我最终尝试了两件事使我意识到这一点:fflush()tputs函数调用可以正常工作之后,很明显问题与缓冲区有关。然后尝试输出到STDERR_FILENO,它也解决了这个问题,实际上stderr是唯一的一个_IONBF,因此没有缓冲。

因此,我最终只创建了一个putchar函数,仅write此而已。

以下是有关三种缓冲区模式的更多信息:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

清除缓冲区标准输入

来自分类Dev

为什么“行缓冲区标准输出以确保自动原子地写行”

来自分类Dev

将子标准输出捕获到缓冲区

来自分类Dev

即使缓冲区已满,也可以自动刷新C中已完全缓冲的输出流吗?

来自分类Dev

在 emscripten 中处理输出缓冲区

来自分类Dev

Java中的非阻塞缓冲区

来自分类Dev

标准C库中缓冲区大小的特殊宏是什么?

来自分类Dev

在正在运行的程序中强制输出缓冲区刷新

来自分类Dev

无需鼠标即可在emacs gdb模式下在共享缓冲区之间切换(在文本终端中)

来自分类Dev

PHP:是否可以获取非阻塞输出缓冲区?

来自分类Dev

读取标准模式下的标准输出从无缓冲更改为行缓冲

来自分类Dev

自动完成终端缓冲区中的单词

来自分类Dev

在Shell脚本中搜索终端缓冲区

来自分类Dev

当SSIS中的C#转换需要同步时,在输出缓冲区中使用AddRow()?

来自分类Dev

标准输出缓冲问题

来自分类Dev

标准输出缓冲问题

来自分类Dev

C ++中的缓冲区大小

来自分类Dev

C ++中的位缓冲区

来自分类Dev

在C ++中解析协议缓冲区

来自分类Dev

C中的缓冲区溢出与获取

来自分类Dev

在C#中同步缓冲区

来自分类Dev

C中自发的缓冲区溢出

来自分类Dev

获取Emacs中任何缓冲区的模式名称

来自分类Dev

在模式行中更改缓冲区名称的颜色

来自分类Dev

Emacs Shell模式在缓冲区中打开文件

来自分类Dev

在node.js缓冲区中搜索字节模式

来自分类Dev

在node.js缓冲区中搜索字节模式

来自分类Dev

c ++字符串模式匹配缓冲区数据

来自分类Dev

在PyCharm中运行或调试时增加输出缓冲区