C言語で標準出力と標準エラー出力の違いを教えて!
こういった悩みにお答えします.
本記事の信頼性
- リアルタイムシステムの研究歴12年.
- 東大教員の時に,英語でOS(Linuxカーネル)の授業.
- 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
- プログラミング歴15年以上,習得している言語: C/C++,Python,Solidity/Vyper,Java,Ruby,Go,Rust,D,HTML/CSS/JS/PHP,MATLAB,Assembler (x64,ARM).
- 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」をGitHubにオープンソースとして公開.
- 2020年1月~現在はアメリカのノースカロライナ州チャペルヒルにあるGuarantee Happiness LLCのCTOとしてECサイト開発やWeb/SNSマーケティングの業務.2022年6月~現在はアメリカのノースカロライナ州チャペルヒルにあるJapanese Tar Heel, Inc.のCEO兼CTO.
- 最近は自然言語処理AIとイーサリアムに関する有益な情報発信に従事.
- (AI全般を含む)自然言語処理AIの論文の日本語訳や,AIチャットボット(ChatGPT,Auto-GPT,Gemini(旧Bard)など)の記事を50本以上執筆.アメリカのサンフランシスコ(広義のシリコンバレー)の会社でプロンプトエンジニア・マネージャー・Quality Assurance(QA)の業務委託の経験あり.
- (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を200本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.
こういった私から学べます.
C言語を独学で習得することは難しいです.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!
目次
C言語の標準出力と標準エラー出力の違い
C言語の標準出力と標準エラー出力の違いを説明します.
3つの標準ファイルストリーム
プログラムには下表の3つの標準ファイルストリームが自動で用意されます.
ファイルディスクリプタ | ファイルストリーム | FILE型構造体のポインタ名 |
---|---|---|
0 | 標準入力 | stdin |
1 | 標準出力 | stdout |
2 | 標準エラー出力 | stderr |
標準入力はファイルディスクリプタstdinからの入力,標準出力はファイルディスクリプタstdoutへの出力,標準エラー出力はファイルディスクリプタstderrへの出力です.
標準入力はscanf/fscanf関数で利用されますが,本記事では利用しないので詳細な説明は省略します.
標準出力と標準エラー出力は主に以下の用途で利用します.
- 標準出力:プログラムのユーザへの提示(例:入力の指示)
- 標準エラー出力:バグやエラー処理が発生した時の表示(例:バグの修正や分析)
これらをきちんと分離することで,効率的にデバッグができるようになります.
標準出力と標準エラー出力のコード
標準出力と標準エラー出力のコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { fprintf(stdout, "stdout\n"); fprintf(stderr, "stderr\n"); return 0; } |
実行結果は以下になります.
1 2 3 4 |
$ gcc fprintf.c $ a.out stdout stderr |
リダイレクトして出力先を分けると以下になります.
標準出力がstdout.txt,標準エラー出力がstderr.txtに書き込まれていることがわかります.
1 2 3 4 5 |
$ a.out 1>stdout.txt 2>stderr.txt $ cat stdout.txt stdout $ cat stderr.txt stderr |
標準出力はデータをバッファに保存してからブロック単位で出力(block buffered)するのに対して,標準エラー出力はデータをすぐに出力します(unbuffered).
例えば,fprintf.cの9~10行目のように標準出力,標準エラー出力の順番にコードを書いた場合,標準エラー出力が先に実行されることがあります.
ここで,バッファがある場合はプログラムが高速になりますが,バッファ内のデータの出力が遅延されます.
これに対して,バッファがない場合は,すぐにデータが出力されますが,プログラムが低速になります.
このようにバッファの有無でトレードオフがあるので,用途に応じて使い分けましょう.
以下のように>&記号で標準出力と標準エラー出力をfprintf.txtファイルに出力した場合,stderr,stdoutの順番で出力されています(3~4行目).
1 2 3 4 |
$ a.out >& fprintf.txt $ cat fprintf.txt stderr stdout |
ファイルストリームのバッファの設定変更
ファイルストリームのバッファの設定を変更することで,stdout,stderrの順番に出力するように設定を変更できます.
setbuf関数ですぐに出力
1 |
void setbuf(FILE *stream, char *buf); |
setbuf関数でファイルストリームのバッファを設定します.
ファイルストリームstreamのバッファbufにNULLポインタを設定すると,すぐに出力します(unbuffered).
setbuf関数でstdoutをNULLに設定したコードは以下になります.
このコードでは,stdoutはstderrのようにすぐに出力する設定(unbuffered)になっています(9行目).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { setbuf(stdout, NULL); fprintf(stdout, "stdout\n"); fprintf(stderr, "stderr\n"); return 0; } |
実行結果は以下になります.
stdout,stderrの順番に出力していることがわかります.
1 2 3 4 5 |
$ gcc fprintf_setbuf.c $ a.out >& fprintf_setbuf.txt $ cat fprintf_setbuf.txt stdout stderr |
fflush関数で強制的に出力
1 |
int fflush(FILE *stream); |
fflush関数でファイルストリームのバッファを強制的に出力(フラッシュ)します.
fflush関数でstdoutの内容を強制的に出力するコードは以下になります.
fflush関数はstdoutとstderrの間で呼び出しています(10行目).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { fprintf(stdout, "stdout\n"); fflush(stdout); fprintf(stderr, "stderr\n"); return 0; } |
実行結果は以下になります.
flush関数を呼び出したことで,stdout,stderrの順番に出力されていることがわかります.
1 2 3 4 5 |
$ gcc fprintf_fflush.c $ a.out >& fprintf_fflush.txt $ cat fprintf_fflush.txt stdout stderr |
まとめ
C言語で標準出力と標準エラー出力の違いを説明しました.
標準出力と標準エラー出力を分離することで,効率的にデバッグができるようになります.
是非,使いこなしましょう!
標準入力を知りたいあなたはこちらからどうぞ.
C言語を独学で習得することは難しいです.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!