前一陣子用C++寫東西,須要往文件裏寫數據,很簡單的代碼,大概是這個樣子: ios
#include <fstream>
using namespace std; 函數
int _tmain(int argc, _TCHAR* argv[])
{
ofstream fout;
fout.open("d://test.dat");
int a = 0x7788; spa
fout.write((char*) &a, sizeof(int));
} 文檔
打開test.dat,內容是77 88 00 00,很正常。 it
打開test.dat,內容是77 88 00 00,很正常。但我要是把a的值改爲0x0a,毛病就出來了,寫出來的東西是:0D 0A 00 00 00! io
要是把a改爲0x770a或者是別的什麼0a,只要是數字中某一個字節是0a,寫出來之後確定變成0D 0A!好比0x770a就變成0D 0A 77! test
更讓人寒的是,即便規定寫出的只能是一個字節,即寫:
fout.write((char*) &a, sizeof(char));
只要a的值的高字節是0a,寫出來同樣變成0D 0A!也就是指定輸出1個字節,實際卻輸出了2個字節! stream
真是讓人費解啊。我一度認爲C++出現了有史以來最莫名其妙的BUG,不過,且慢…… gc
0A是什麼?0D 0A又是什麼?這個問題的解原來在這裏。先查查C++的文檔,裏面說明,ofstream的open函數,第二個參數指明打開方式,缺省爲ios_base::out,即按照字節流的方式輸出文本。再看看0A究竟是什麼,原來ASCII的0A是換行,也就是/n,再想一想,Windows系統下的換行是如何處理的?/r/n啊。原來…… 數據
原來按照字節流的形式輸出文本時,ofstream會自動將輸出的/n變成/r/n,以適應WIndows系統,結果以輸出數據的角度看來,這個正常的舉動就變成了不可解的「0A變成0D 0A」。
既然如此,答案也出來了,查查文檔,將打開文件的一句改爲:
fout.open("d://test.dat", ios_base::out | ios_base::binary); 搗亂的0A終於歸位了。