10

発生したばかりの行を「上書き」する必要があるフィルター(端末出力用のパイプ内)を作成しています。これは、aに到達するまでstdinをstdoutに文字ごとに渡し\n、次に特別な動作を呼び出すことによって機能します。私の問題は、行の先頭に戻る方法に関するものです。

私が最初に考えたのは、\rまたはANSIシーケンスを使用することでした\033[1Gただし、行が端末で折り返されるのに十分な長さである場合(したがって、行がスクロールする原因となった場合)、これらはカーソルを現在の物理行に戻すだけです。

私の2番目のアイデアは、行の長さ(前から渡された文字数)を追跡し、それを何度も\nエコーすることでした。\bただし、行に制御文字またはエスケープシーケンス(および場合によってはUnicode?)が含まれている場合は、問題が発生します。

すべての特別なシーケンスを検索し、これを使用して文字数を調整する以外に、これを実現する簡単な方法はありますか?

4

3 に答える 3

3

コンソールに書き込まれたときに最後に書き込まれた行を確実に消去する「魔法のシーケンス」があったとしても、出力で行とシーケンスを取得します(コンソールでは隠されていますが)。誰かが出力をファイルに書き込んだり、パイプを介して他のフィルターに渡したりするとどうなるか考えてみてください。彼らはそのような入力を処理する方法を知っていますか? また、コンソールに直接書き込む以外の場所に書き込む可能性を排除しているとは言わないでください。遅かれ早かれ、誰かが出力をリダイレクトしたいと思うでしょう。

これを行う正しい方法は、処理されるたびに各行をメモリにバッファリングし、それを出力するかどうかを決定することです。これを回避する方法は本当にありません。

于 2009-06-30T18:35:24.663 に答える
2
$ cat> test.sh <<'EOF'
>#!/ bin / sh
> tput sc
> echo'これは非常に長い複数行の文字列です:....................................。 .................................................。 ……」
> tput rc
>echo'私は戻っていくつかのものを上書きしました!!!!'
>エコー
> EOF
$ sh test.sh
私は戻って、いくつかのものを上書きしました!!!! ......................................。
.................................................。 ...。

save_cursorデータベースでおよびrestore_cursor文字列機能を探しterminfoます。

于 2009-06-26T19:08:20.507 に答える
0

次の単純な方法で端末の寸法を照会できますioctl

#include <sys/types.h>
#include <sys/ioctl.h>

// ...

struct winsize ws;
ioctl(1, TIOCGWINSZ, &ws);

// ws.ws_col, ws.ws_row should now contain terminal dimensions

このようにして、行末を超えて何かを印刷するのを防ぎ、単に\rメソッドを使用することができます。

于 2009-06-26T18:10:04.680 に答える