標準ストリーム(英: standard streams)とは、UNIXやUnix系オペレーティングシステム (OS) において、プログラムの活動実体であるプロセスとその実行環境(通常は端末)の間の接続として、(プロセスから見ると)あらかじめ確立されている入出力チャネル(パイプ)である。OSのカーネルではなくシェルで実装されている機能だが、広く使われているため標準化されている。UNIXやUnix系OSでは3つの入出力ストリーム(標準入力、標準出力、標準エラー出力)が定義される。

一部のプログラミング言語の実装では、UNIXやUnix系以外のシステムでもUnixと同様の使い勝手を提供するよう、これらを模倣するものがある。MS-DOSにはさらに、シリアルポートに対応する標準補助入出力 (stdaux)、プリンターに対応する標準プリンター出力 (stdprn) もあり、今でもWindowsで`AUX`や`PRN`という名前をファイルやコマンド等に使おうとすると問題を起こしたりするのは、これらに関してMS-DOSとの互換性があるためである。

## 背景

UNIX以前の多くのOSでは、プログラムは明示的に適当な入出力に接続する必要があった。多くのシステムにはOS固有の複雑な事情があり、環境設定をしたり、ローカルなファイルテーブルにアクセスしたり、必要なデータセットを指定したり、カードリーダー、磁気テープドライブ、ディスクドライブ、ラインプリンタ、カードパンチ、対話型端末などを正しく扱うといったプログラミング以前のハードルが多数存在した。

UNIXはこの状況に対していくつかの重要な進化を遂げている。その1つが「抽象デバイス(英: abstract device)」である。これはプログラム自体がやり取りするデバイスに関する知識を持たなくて済むようにしたものである。古いOSではプログラマはレコード構造を知っておく必要があり、直交性のないことが多いデータ意味論やデバイス制御を扱う必要があった。UNIXはデータストリームという概念によってこのような複雑さを排除した。データストリームとは逐次的なデータバイト列であり、End Of Fileまでリード可能である。プログラムはまた好きなだけバイト列を出力でき、事前にバイト数を宣言しておく必要もないし、それらがどのようにグループ化されているかを宣言する必要もない。

もう1つのUNIXの成し遂げたブレークスルーは、自動的に入力と出力を関連付けることであり、典型的な入力-処理-出力型プログラムでは入出力の設定を何もする必要がない。対照的にそれ以前のOSでは複雑なジョブ制御言語を使ってコネクションを確立するか、それとほぼ同等のことをプログラム本体で行う必要があった。

UNIXが標準ストリームを提供したことで、そのC言語実行環境もそれをサポートするようになった。結果として、多くのC言語実行環境(および派生言語の実行環境)はOSが何であっても同等な機能を提供するようになっている。

## 標準入力 (stdin)

標準入力(英: standard input, stdin)はプログラムに入ってくるデータ(テキストであることが多い)である。プログラムは read 操作を使ってデータ転送を要求する。全てのプログラムが入力を要求するわけではない。例えばdirやlsプログラム(ディレクトリ内のファイル名の一覧を表示する)は、標準入力からのデータを使わないで処理を行う。

リダイレクトしない限り、標準入力はプログラムを起動した端末のキーボードになっている。

標準入力のファイル記述子は0である。POSIXの `<unistd.h>` では `STDIN_FILENO` と定義されている。対応する `<stdio.h>` での変数は `FILE* stdin`、`<iostream>` での変数は `std::cin` である。

## 標準出力 (stdout)

標準出力(英: standard output, stdout)はプログラムが書き出すデータのストリームである。プログラムは write 操作を使ってデータ転送を要求する。全てのプログラムが出力を要求するわけではない。例えばファイル改名コマンド(mv、move、ren など)は何も出力しない。

このストリームのデフォルト宛先はプログラムを起動した端末のディスプレイになっている。リダイレクトにより容易に宛先を変更できる。

標準出力のファイル記述子は1である。POSIXの`<unistd.h>`では`STDOUT_FILENO`と定義されている。対応する`<stdio.h>`での変数は`FILE* stdout`、`<iostream>`での変数は`std::cout`である。

## 標準エラー出力 (stderr)

標準エラー出力(英: standard error, stderr)は、エラーメッセージや診断メッセージを出力するためのもう1つの出力ストリームである。標準出力とは独立しているため、一方だけをリダイレクトすることができる。デフォルトでは端末(のディスプレイ)になっており、標準出力がリダイレクトされていて画面に表示されなくとも、エラーメッセージだけはユーザーが目にするようになっている。例えば、パイプで出力が他のプログラムの入力に接続されている場合でも、標準エラー出力は直接端末のディスプレイに届く。

標準出力と標準エラー出力を同じ出力先(端末など)にリダイレクトすることもよくある。バッファが関与しない場合、メッセージはプログラムが書いた順序で現れる。典型的な例として、標準エラー出力がバッファリングされておらず、標準出力が行単位でバッファリングされている場合、後から標準エラー出力に書かれたメッセージが先に端末上に表示されることがある(標準出力のバッファが満杯になっていない場合)。

標準エラー出力のファイル記述子は2である。POSIXの`<unistd.h>`では`STDERR_FILENO`と定義されている。対応する`<stdio.h>`での変数は`FILE* stderr`、`<iostream>`での変数は2つあり`std::cerr`と`std::clog`である。前者はバッファリングされておらず、後者はC++の他のストリームと同様にバッファリングされている。

## 歴史

### 1950年代: FORTRAN

FORTRANにもUNIXのようなファイル記述子があり、`UNIT=5`がstdin、`UNIT=6`がstdoutを表す。

### 1960年: ALGOL 60

ALGOL 60には、標準ストリーム(ファイルアクセス)の概念が存在しない。

### 1968年: ALGOL 68

ALGOL 68では、入力 (input) と出力 (output) をあわせてtransputと呼ぶ。Cornelis H. A. Kosterはtransput標準を定義した。この標準には`stand in`、`stand out`、`stand error`、`stand back`がある。

例:

| 入力: | 出力: |
| --- | --- |
| ``` 3.14159 ``` | ``` Number is: +3.142 OR Number is: +3.142! ``` |

### 1970年代: CとUnix

C言語では、stdin、stdout、stderrのストリームはUnixのファイル記述子 0、1、2にそれぞれ対応する。

### 1995年: Java

Javaでは、標準ストリームは`System.in` (stdin)、`System.out` (stdout)、`System.err` (stderr) で参照される。

### 2000年代: .NET

C#などの.NET言語では、標準ストリームは`System.Console.In` (stdin)、`System.Console.Out` (stdout)、`System.Console.Error` (stderr) で参照される。stdinおよびstdoutストリームの基本的な読み書きの場合、クラス`System.Console`を使って直接アクセスすることもできる(つまり、`System.Console.Out.WriteLine()`の代わりに`System.Console.WriteLine()`を使える)。

`System.Console.In`、`System.Console.Out`、`System.Console.Error`は `System.IO.TextReader` (stdin) および `System.IO.TextWriter` (stdout, stderr) オブジェクトであり、テキストベースの標準ストリームにしかアクセスできない。標準ストリームへの完全バイナリアクセスには`System.IO.Stream`オブジェクトを使う必要があり、それぞれ`System.Console.OpenStandardInput()`、`System.Console.OpenStandardOutput()`、`System.Console.OpenStandardError()`で得られる。

`System.Diagnostics.Process`クラスを使うと、そのインスタンスプロパティ`StandardInput`、`StandardOutput`、`StandardError`を使ってそのプロセスの標準ストリームにアクセスできる。

### GUI

グラフィカルユーザインタフェース (GUI) では滅多に標準ストリームを使わない。当然、GUIプログラムをリダイレクトしたり、GUIプログラムでパイプを使うことはない。GUIにとって標準ストリームに近いのはコピー・アンド・ペーストであろう。しかし、ユーザーの操作を必要とするため、多数の「ペースト」を行うのは効率的ではない。特筆すべき例外としてdwmというタイル型ウィンドウマネージャでは、stdout上のデータをステータスバーに直接表示する。

特にUnix系の一部のGUIプログラムは、デバッグ情報を標準エラー出力に書き込んでいることがある。また、標準入力にファイルを指定する形式で働くものもあり、Unix系のメディアプレーヤーに多い。

GTK-serverでは、GUIを構築するインタプリタ型プログラムとのインタフェースにstdinを使うことができる。