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,&termios_backup);
    return (0);
}

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

问题是:

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

我怀疑:

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

谢谢! :)

解决方法

✅已解决:

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

return ( <div className="googleMapContainer"> {console.log(window.google)} <LoadScript googleMapsApiKey={googleApiKey}> <div className="googleMap"> <GoogleMap 参数中使用putchar是个问题,因为putchar像printf一样被缓冲。 我最终尝试了两种方法使我认识到这一点:在tputs函数调用可以正常工作之后,fflush()显然因此问题与缓冲区有关。 然后尝试输出到STDERR_FILENO,它也解决了这个问题,实际上stderr是唯一的tputs,所以没有缓冲。

所以我最终创建了一个只有_IONBF的putchar函数,就是这样。

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