画面に文字を出力 ~ 標準出力と標準エラーへの出力
ここでは、簡単な C 言語のプログラムを作成して、文字を出力してみましょう。
次の内容を foo.c という名前のファイルに保存してください。
#include <stdio.h>
int main() {
printf("Hello!\n");
return 0;
}
ソースコードの内容を簡単に説明します。
#include <stdio.h>
あとで printf という関数を使うので stdio.h というヘッダーファイルをインクルードしています。
int main() {
C 言語のプログラムは main という名前の関数から実行されますので、main という名前の関数を用意します。戻り値は int 型にしておきます。
printf("Hello!\n");
printf 関数は「標準出力」に文字を出力します。ここでは Hello! という文字を出力します。
このプログラムはコマンドラインから実行されますが、「標準出力」というのはこの場合、コマンドラインの画面のことです。
return 0;
最後に main 関数を終わるときに、正常終了を表す 0 を return で返します。
Linux では次のようにコンパイルして実行できます。
gcc -o foo foo.c
./foo
Hello!
Windows でも同様です。コンパイラは cl です。
cl foo.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25019 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
foo.c
Microsoft (R) Incremental Linker Version 14.10.25019.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:foo.exe
foo.obj
foo
Hello!
Visual Studio を使うときのコマンドラインからのビルド方法については 「Visual Studio デベロッパーコマンドプロンプトを使った C/C++ プログラムの構築」 をみてください。
さて、プログラムをしっかりみてきましたが、ポイントは printf を呼ぶと 「標準出力」に出力するということです。
標準出力というのは UNIX/Linux 系ではファイルデスクリプタ 1 と決まってます。しかし、Windows ではファイルハンドル 1 などとは決まっていません。 「標準出力に出力する」ということだけです。
標準エラーに出力する
エラーメッセージを出力する場合は通常、正常の出力と区別するために「標準エラー」に出力します。
コマンドラインから実行すると、通常標準出力も標準エラーもどちらもスクリーンに表示されることには代わりありませんので、 一見「どっちでも同じじゃないの?」と思ってしまいます。しかし、実際は出力されているファイルハンドル (ファイルデスクリプタ) は異なります。
標準エラーに出力するには、明示的に fprintf 関数を使って stderr に出力します。
fprintf は第一引数に、ストリームを識別するファイルポインタを受け取り、そのストリームにフォーマットされた文字列を出力します。
#include <stdio.h>
int main() {
fprintf(stderr, "Hello, stderr!\n");
return 0;
}
gcc foo.c
./a.out
Hello, stderr!
見ただけでは標準出力と区別できないので、パイプを通して確認してみましょう。
パイプやリダイレクトに関しては「リダイレクトの基本」をみてください。
上の a.out の出力をそのまま tr コマンドに送ろうとしてもうまくいきません。大文字に変換されていません。
./a.out | tr 'a-z' 'A-Z'
Hello, stderr!
標準エラーのファイルデスクリプタ 2 を指定して標準出力 &1 にリダイレクトして、それからパイプに送ると、 次のように確かに tr コマンドが受け取れるので大文字に変換されました。
./a.out 2>&1 | tr 'a-z' 'A-Z'
HELLO, STDERR!
以上、標準出力と標準エラーに出力する方法と、それらの違いについて動作を確認しながら説明しました。