我剛剛目睹了std::ofstream::write
方法的瘋狂bizzare行爲。我正在編寫自己的Windows'BMP文件格式處理,其中包括將位圖保存到文件 - 這是一個介紹。給定參考std::ofstream
對象,這是一個負責編寫位圖文件頭的子例程。std :: ofstream重複並丟失書面數據無故
void
BitmapFileManager::FileHeader::save(std::ofstream& fout) const
{
word w;
dword dw;
char const* cw = reinterpret_cast<char*>(w);
char const* cdw = reinterpret_cast<char*>(dw);
uint const sw = sizeof(w);
uint const sdw = sizeof(dw);
fout.write(&sig1, sizeof(sig1));
fout.write(&sig2, sizeof(sig2));
dw = toLittleEndian(size); fout.write(cdw, sdw);
w = toLittleEndian(reserved1); fout.write(cw , sw);
w = toLittleEndian(reserved2); fout.write(cw , sw);
dw = toLittleEndian(pixelsOffset); fout.write(cdw, sdw);
}
在這裏紀念的唯一的事情就是sig1
和sig2
都是char
類型,sizeof(word) = 2
和sizeof(dword) = 4
的。該代碼應該導致兩次將一個字節寫入文件,然後是四個字節的塊,兩個兩個字節的塊,最後是四個字節的塊。
採取看看結果的十六進制轉儲(也有一些事情,跟着,卻忽略了他們):
00000000 42 4d 42 4d 00 00 00 05 00 05 42 4d 00 00 28 00 |BMBM......BM..(.|
sig1
和sig2
印刷兩次,這實際上是B
和一個合適的值M
,一開始也有一些奇怪的原因,在第11和第12字節。我不承認這一行中的其他價值。但是,看看,如果我每write
之間增加一個調試字節會發生什麼:
void
BitmapFileManager::FileHeader::save(std::ofstream& fout) const
{
word w;
dword dw;
char const* cw = reinterpret_cast<char*>(w);
char const* cdw = reinterpret_cast<char*>(dw);
uint const sw = sizeof(w);
uint const sdw = sizeof(dw);
char nil = '*';
fout.write(&sig1, sizeof(sig1));
fout.write(&nil, sizeof(nil));
fout.write(&sig2, sizeof(sig2));
fout.write(&nil, sizeof(nil));
dw = toLittleEndian(size); fout.write(cdw, sdw);
fout.write(&nil, sizeof(nil));
w = toLittleEndian(reserved1); fout.write(cw , sw);
fout.write(&nil, sizeof(nil));
w = toLittleEndian(reserved2); fout.write(cw , sw);
fout.write(&nil, sizeof(nil));
dw = toLittleEndian(pixelsOffset); fout.write(cdw, sdw);
fout.write(&nil, sizeof(nil));
}
十六進制轉儲則
00000000 42 2a 4d 2a 6c 3b 78 a0 2a 00 05 2a 00 05 2a 6c |B*M*l;x?*..*..*l|
00000010 3b 78 a0 2a 28 00 00 00 28 00 00 00 28 00 00 00 |;x?*(...(...(...|
看起來這是完全正常的。沒有重複,並且*
按照它應該將字符串分成1-1-4-2-2-4
字節的序列。有人能幫我找到這個的原因嗎?這是編譯錯誤嗎?我在Mac OS X Leopard上使用gcc version 4.0.1 (Apple Inc. build 5490)
,但是其他級別沒有任何改變。
你可以減少到最小的獨立測試案例嗎? (見http://sscce.org) –
當然,你的意思是寫'char const * cw = reinterpret_cast(&w)'(注意最後的'&'運算符)而不是'...(w)',同樣對於'cdw' /'dw'?我很驚訝,運行沒有崩潰。 –
我當然做到了。現在它完美地工作。但行爲仍然很奇怪。 –