「標準出力」というのは、慣用的な出力を行うためのテキストストリームの結合先のことで、多くの場合、画面への表示になっています。画面といっても、Windows などで見慣れたウィンドウとかではなく、コマンドライン(Windows でいえばコマンドプロンプト)です。
しかし、プログラムの呼び出し方しだいで、標準出力は、画面への表示ではなく、ファイルや他のプログラムが操作するストリームに結合することもできます。例えば、CGI では標準出力への書き込みはブラウザへのレスポンスとなります。また別の状況では標準出力の結合先がシリアルポートになることもあるでしょう。
std::cout
標準出力に書き込むための最も一般的な方法は、std::cout
を使用することです。std::cout
に対して <<
演算子を用いることで、
int main()
{
std::cout << "Hello, World!";
}
とすれば、<<
演算子の右辺に記述したオブジェクトの値が標準出力に書き込まれます。上のサンプルコードでも分かるように、std::cout
を使うときは <iostream> ヘッダをインクルードする必要があります。
また、末尾に改行を書き込みたい場合には、'n'
または "n"
を書き込んでもよいのですが、普通は std::endl
を使用します。
std::endl
は、改行文字 n
を書き込んだ後、ストリームが管理しているバッファの内容をフラッシュ(実際に吐き出)します。
std::cout
を使うメリットは、<<
演算子さえ定義してやれば、ユーザー定義型も含めて、どんな型のオブジェクトであっても同じ構文で書き込み処理を記述できる点にあります。デメリットとしては、ややオーバーヘッドが大きいことが挙げられます。ただ、速度面に関しては、元々入出力は遅いものですし、サイズ面に関しては、プログラムの規模がある程度以上大きくなると、その影響は微々たるものになります。std::cout
を避ける、または他の方法を用いる積極的な理由がなければ、std::cout
を使うようにしましょう。
std::wcout
std::wcout
は std::cout
とよく似ています。何が違うかというと、std::cout
に対して書き込むことができる文字は char
型であり、文字列は char*
または std::string
型なのに対して、std::wcout
に書き込むことができる文字は wchar_t
型であり、文字列は wchar_t*
または std::wstring
型だということです。つまり、std::wcout
はワイド文字(列)を扱うためのものです。
std::cout
は char
型のようなナロー文字(列)しか扱えません。逆に、std::wcout
は wchar_t
型のようなワイド文字(列)しか扱えません。両方を混在させることは原則としてできないのです。どうしても混在させたい場合は、自分で <<
演算子を多重定義するなどしなければなりません。 また、ひとつのプログラムの中で、std::cout
と std::wcout
を混在させるべきではありません。
int main()
{
std::wcout << L"Hello, World!" << std::endl;
}
なお、処理系によっては std::wcout
がサポートされていない場合があります。規格上はサポートしなければならないのですが、実際に使う処理系がサポートしないのであれば、使用を控える以外にありません。
なお、std::wcout
を用いて日本語を出力したい場合には、ロケールの設定が必要になります。ロケールを設定するには、std::wcout
の imbue
メンバ関数を使用します。このメンバ関数に設定しようとするロケールを渡すことになります。例えば、
#include <locale>
int main()
{
std::wcout.imbue(std::locale(""));
std::wcout << L"こんにちは、世界!" << std::endl;
}
のようにです。上のサンプルコードでは、ロケールに ""
を設定しています。日本語の OS 環境であれば、多くの場合これで問題ありませんが、もっと明示的に日本語ロケールを設定するには、処理系定義の文字列、例えば "ja"
とか "japanese"
などを渡す必要があります。
処理系によっては、std::setlocale
によってグローバルロケールを設定しておかないと誤動作することがあります。処理系の不具合ですが、ときどき遭遇するので要注意です。
stdout
最後は C との互換性のために用意された stdout
を使う方法です。std::cout
の使い方が分からないといった後ろ向きな理由を除けば、std::cout
や std::wcout
ではなく、stdout
を使わなければならない状況は多くありません。しかし、例えば FILE*
型の他のストリーム(テンポラリファイルやパイプなど)と出力先を切り替えたい場合などは、そうせざるを得ないこともあるでしょう。
stdout
を用いて標準出力に文字列を書き込むには、
int main()
{
std::fputs("こんにちは、世界!n", stdout);
}
のようにします。数値を書き込むには、printf
または fprintf
を使うことになりますが、オブジェクトの型によって異なる書式を指定しなければなりません。
int main()
{
std::printf("%d %fn", 123, 4.56);
}
printf
等では、第 1 引数である書式文字列に続く引数の型はまったくチェックされません。また、クラス型のオブジェクトを引数に渡すと未定義の動作を引き起こします。そのため、プログラマの責任で正しい書式を記述しなければなりません。