標準入出力のバイナリモード
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
[[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 Edi...
と共通のコードが書けたので、メモしておく。
以下は、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 はこの関数一回の
呼び出しですべての標準入出力に影響を与えるが、
一番最後の書き方は、このことが見えにくくなるので、
あまり薦めない。
終了行:
[[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 Edi...
と共通のコードが書けたので、メモしておく。
以下は、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 はこの関数一回の
呼び出しですべての標準入出力に影響を与えるが、
一番最後の書き方は、このことが見えにくくなるので、
あまり薦めない。
ページ名: