[解決済み] 出力がファイルにリダイレクトされるとき、printf()とsystem()の結果が間違った順番になる [duplicate] 。
質問
私はmyprogramという実行ファイルにコンパイルされるCプログラムを持っています。これはそのメイン関数です。
int main(int argc, char ** argv) {
printf("this is a test message.\n");
system("ls");
return 0;
}
を実行すると
myprogram > output.txt
を Linux シェルで実行し、output.txt を調べると、出力は
ls
の上に記載されている "this is a test message."
と表示されるのですが、逆であるべきな気がします。なぜこのようなことが起こるのでしょうか。また、どうすれば "this is a test message" が output.txt の一番上に表示されるようになるのでしょうか。
重要であれば、私は C 言語とコマンドラインでの作業の両方が初めてです。
どのように解決するのですか?
デフォルトの出力先
stdout
は
ラインバッファリング
であり、ターミナルに接続されているときは つまり、バッファが一杯になったときや、改行を追加したときにバッファをフラッシュします。
しかし
もし
stdout
がターミナルに接続されていない場合、例えば、プログラムの出力をファイルにリダイレクトするような場合は
stdout
は
フルバッファリング
. つまり、バッファは満杯になったときか、明示的にフラッシュされたとき(プログラムが終了したときに起こる)、フラッシュされ実際に書き込まれます。
これは、あなたのコードから開始された別のプロセスの出力 (たとえば
system
を呼び出したときのような)別のプロセスの出力が最初に書かれる可能性が高いということです。なぜなら、そのプロセスのバッファはそのプロセスが終了したときにフラッシュされ、自分のプロセスよりも先になるからです。
リダイレクト(またはそのためのパイプ)を使用するとどうなるか。
-
あなたの
printf
の呼び出しはstdout
バッファに書き込みます。 -
は
system
関数は新しいプロセスを開始し、それ自身のバッファに書き込みを行います。 -
外部プロセス(あなたの
system
によって起動された) 外部プロセスが終了すると、そのバッファはフラッシュされ、書き込まれます。あなた自身のプロセス内のあなた自身のバッファは触れません。 -
自分自身のプロセスが終了し、自分の
stdout
バッファがフラッシュされ、書き込まれます。
正しい(あるいは少なくとも期待される)順序で出力を得るには、次のように呼び出します。
fflush
を呼び出す前に
system
を呼び出す前に、明示的にフラッシュする必要があります。
stdout
を呼び出すか、あるいは
setbuf
を呼び出すと、バッファリングを完全に無効にすることができます。
関連
-
C 構造体定義エラー: '['トークンの前に一次式があることが予想される
-
[解決済み] Code::Blocks アプリケーションをコンパイルできない
-
[解決済み] Bashで標準出力と標準エラーの両方をファイルにリダイレクトして追記する方法
-
[解決済み] C言語における「static」の意味とは?
-
[解決済み] 出力をファイルや標準出力にリダイレクトする方法
-
[解決済み] ++iとi++の違いは何ですか?
-
[解決済み] C言語で関数をパラメータとして渡すにはどうすればよいですか?
-
[解決済み] ファイル内検索と置換、ファイルの上書きがうまくいかず、ファイルが空になってしまう
-
[解決済み] .aファイル、.soファイルとは何ですか?
-
[解決済み] なぜC言語では構造体を頻繁にtypedefする必要があるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[C] レポートエラー 代入の左オペランドとしてlvalueが必要
-
C++の配列コピー
-
エラー: 宣言されていない識別子 'bool' の使用と C コンパイラでの問題点
-
C: 1を求める! + 2! + 3! + ... + n! (ループ)
-
警告:符号付き整数式と符号なし整数式の比較 [-Wsign-compare]
-
[解決済み] c または c++ 用のシンプルな 2 次元クロスプラットフォームグラフィックスライブラリ?[クローズド]
-
[解決済み] C関数から文字列を返す
-
[解決済み] printfは、フォーマット文字列の中に改行がないと、呼び出し後にフラッシュしないのはなぜですか?
-
[解決済み] なぜ16進数には0xがつくのですか?
-
[解決済み] FortranはC言語よりも重い計算を最適化しやすいですか?