29

たくさんのファイルを処理するMacOSX用のコマンドラインツールを書いています。現在処理中のファイルをユーザーに表示したいのですが、何億ものファイルがターミナルウィンドウを汚染することは望ましくありません。

代わりに、1行を使用してファイルパスを出力し、その行を次のファイルに再利用したいと思います。std::coutこれを達成するために出力する文字(または他のコード)はありますか?

また、このツールをWindows用に再ターゲットしたい場合、ソリューションは両方のプラットフォームで同じでしょうか?

4

3 に答える 3

32

「\r」は、WindowsとMacOSXの両方で機能するはずです。

何かのようなもの:

std::cout << "will not see this\rwill see this" << std::flush;
std::cout << std::endl; // all done
于 2010-06-16T23:49:59.500 に答える
2

私はMacにアクセスできませんが、純粋なコンソールの観点からは、これはキャリッジリターンとラインフィード文字の処理方法に大きく依存します。文字通りどちらか一方をコンソールに送信できる場合は、キャリッジリターンだけを送信する必要があります。

Macは、キャリッジリターンとラインフィードの両方を* nix&windowsとは異なる方法で処理すると確信しています。

インプレースアップデート(現在の行を上書きするなど)を探している場合は、cursesライブラリを確認することをお勧めします。これは、あなたが探していることを行うためのプラットフォームに依存しない手段を提供するはずです。(標準のC ++を使用していても、プラットフォームに依存しない、求めているものの手段がないため)。

于 2010-06-16T23:58:23.460 に答える
0

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のような素晴らしいシェルはこれをチェックします)。

于 2020-05-15T21:29:21.537 に答える