问题描述
想法是能够像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
函数的标志TCSADRAIN
和tcsetattr
来获得相同的结果。
谢谢! :)
解决方法
✅已解决:
好吧,对于遇到这种情况的任何人,这都很有趣,因为它使我学到了很多东西(嗯,这是一个学校项目,所以...)。
在 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函数,就是这样。
以下是有关三种缓冲模式的更多信息: