c++のeofは事後確認
C++でfstreamを使ってファイルアクセスをしたとき、eofの動きがCのFileライブラリとかの動きと違うことに気がついた。Cの場合は「読む前にもうデータがないことがわかる」が、C++のstreamの場合は「読んでみて初めてデータがないことがわかる」である。
を動かすと、
とよけいなfffffff(元はcharの0xff)がつく。最後の改行(LF=0x0a)を読んだあとeof()はtrueにならないのである。データがない状態でgetやreadをして、ないことがわかるとやっとeof()がtrueになるのである。さきほどのプログラムを期待通りに動かすには、読む前にeofチェックではなく、読んだ後にチェックすべきである。
これは最初に確認したのはVisual C++だが、cygwin上のgppでも同じ動きだったので多分linux上のgppもいっしょ。いまさら周知の事実なんだろうが、今頃気が付いたのでメモ。
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(void)
{
ifstream ifs("test.txt");
char c;
while (!ifs.eof()) {
c = ifs.get();
cout << hex << (int)c << endl;
}
return 0;
}
$ cat test.txt
abc
$ ./test
61
62
63
a
ffffffff
$
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(void)
{
ifstream ifs("test.txt");
char c;
for(;;) {
c = ifs.get();
if (ifs.eof()) {
break;
}
cout << hex << (int)c << endl;
}
return 0;
}