[[C++のiostream]]

* 標準入出力のバイナリモード [#r7acad8a]
例えば K&R のプログラミング言語 C 第2版
の 1.5.2 の例題の文字数のカウントを
Windows でやると <CR><LF> の対で1文字とカウント
される。つまりファイルを redirect してやると、
ファイルのバイト数とカウント数が一般には一致しない。
標準出力も同様で '\n' 一文字を出力すると、<CR><LF>
の対が出力される。

これは Windows では、標準入出力が default で
テキストモードであるためである。これはこれで
便利なこともあるが、バイナリモードで行いたいことも
ある。

** ファイル入出力なら open 時に指定できるが、、 [#d8dc6db2]
C でも C++ でもファイル入出力に関しては規格上 open 時に
モードを設定することができるので、
これを使えばよいが、標準入出力はプログラムの最初から
すでに open されており、ファイルとして実装されて
いる保障も無い。更にモード変更の仕組みも用意されて
いない。
というわけ処理系依存にならざるを得ない。
というわけで処理系依存にならざるを得ない。

** gcc と VC 共通コード [#n1dd42ba]
一応、gcc/g++ (mingw 3.4.5) と Visual C++ 9.0 Express Edition
と共通のコードが書けたので、メモしておく。
以下は、K&R の 1.5.2 の文字数をカウントする例題を
Windows バイナリ化したものである。

 #include <iostream>
 #include <cstdio>
 #include <fcntl.h>
 #include <io.h>
 
 int main()
 {
 	std::ios_base::sync_with_stdio(false);
 	_setmode(_fileno(stdin),_O_BINARY);
 	std::ios_base::sync_with_stdio(true);
 
 	long nc = 0;
 	char c;
 	while(std::cin.get(c))
 		++nc;
 	std::cout << nc << std::endl;
 	return 0;
 }

** sync_with_stdio について [#q16b3981]
ここで、sync_with_stdio は ios_base の静的公開関数で
あるので、これを継承している ios でも istream でも
ostream でも、あるいはそのオブジェクトである cin や
cout からでも呼び出せる。例えば

 	std::ios::sync_with_stdio(false);
 	_setmode(_fileno(stdin),_O_BINARY);
 	std::ios::sync_with_stdio(true);

としてもよいし、

 	std::cin.sync_with_stdio(false);
 	_setmode(_fileno(stdin),_O_BINARY);
 	std::cin.sync_with_stdio(true);

としてもよい。ただし、sync_with_stdio はこの関数一回の
呼び出しですべての標準入出力に影響を与えるが、
一番最後の書き方は、このことが見えにくくなるので、
あまり薦めない。

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS