私は学校のプロジェクトに取り組んでいます(非常に基本的なシェルを構築しています)。
アイデアは、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' で char を出力し、'q' で元の端末モードを中断して復元します。
問題は次のとおりです。
「q」でループを中断するまで何も起こらないため、何かを入力するたびにバッファリングされているように見えます。この時点で、出力が画面に表示されます。b を 5 回入力すると、5 回の b が表示され、「c」を入力すると画面がクリアされます。ただし、「q」を入力した後のみ。動作は、元の端末モードを復元する場合も復元しない場合も同じです。( の前の最後の行return)
私が疑うもの:
コードを非常に短くしてすべてのリターンをチェックした後、端末モードを変更する方法に問題があるだけだと思う傾向がありますか? フラグTCSAFLUSHと関数を試してみると、同じ結果が得られましたTCSADRAIN。tcsetattr
ありがとう !:)