Nathan Ernstの回答が言うように、これを行うための堅牢で適切な方法が必要な場合は、curses(具体的にはncurses )を使用してください。
うまくいく傾向のある手間のかからないハックの方法が必要な場合は、続行してください...
Linux、UNIX、MacOS、Windowsなどのコマンドライン端末は、10進数の文字13を含む基本的なASCII制御文字の小さなセットをサポートする傾向があります。これはキャリッジリターンと呼ばれ、C++では「\r」または同等に8進数でエンコードされます。 \015'またはhex'\x0D'-端末に行の先頭に戻るように指示します。
あなたが一般的にやりたいことは...
int line_width = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 80;
std::string spaces{line_width - 1, ' '};
for (const auto& filename : filenames) {
std::cout << '\r' << spaces << '\r' << filename << std::flush;
process_file(filename);
}
std::cout << std::endl; // move past last filename...
これは、スペースの文字列を使用して、次のファイル名を書き込む前に古いファイル名を上書きするため、短いファイル名の場合、以前の長いファイル名の末尾の文字は表示されません。
はstd::flush
、C ++プログラムがOSwrite()
関数を呼び出して、ファイルの処理を開始する前にテキストを端末に送信することを保証します。それがないと、更新に必要なテキスト\r
(スペース、\r
ファイル名)がバッファーに追加され、バッファーがいっぱいになるとOSにのみ書き込まれます(たとえば、4kチャンク)。そのため、表示されるファイル名は数十のファイルより遅れます。処理中の実際のファイルの背後にあります。さらに、バッファが4k(4096バイト)で、ある時点で4080バイトがバッファリングされているとすると、次のファイル名のテキストが出力されます。\r
バッファに15個のスペースが収まります。自動フラッシュすると、画面上の行の最初の15文字が消去され、前のファイル名の残りの部分(15文字より長い場合)が残り、画面を更新する前に、バッファが再びいっぱいになります(それでも無計画に)。
ファイナルstd::endl
は、ファイル名を印刷している行からカーソルを移動するだけなので、「すべて完了」と書くことができます。またはmain()
、最後のファイル名の一部を上書きする可能性のない、そのままにしてシェルプロンプトをきれいな行に表示することもできます。 (zshのような素晴らしいシェルはこれをチェックします)。