2011-11-28 86 views
2

我有一個二進制文件(test.bin),它有兩個unsigned int值,分別是1000和4000。 使用下面的代碼,我想用第一個寫入功能將第一個數字更改爲5000,然後我想讀取第二個數字並用4000-2000 = 2000重寫它。 但是,程序更改爲1000到5000,但它確實不會更改4000到2000.即使使用file.flush()或file.sync(),它也沒有任何作用。有趣的是,當我把file.tellg()或file.tellp(),它的工作原理,我想要的。 (我巧合發現它) 這在Linux和Windows上都會發生。在Linux上,我嘗試用g ++編譯它。 sizeof(unsigned int)= 4,我確定程序可以打開test.bin。對C++文件的後續讀寫操作

#include <fstream> 
#include <iostream> 

using namespace std; 

int main(){ 
    fstream file; 
    unsigned int data, buffer; 
    data=5000; 
    file.open("test.bin", ios::binary | ios::in | ios::out); 

    file.write((char*)&data,4); // will change first number to 5000 

    // file.flush(); // Nothing changes if I delete comment signs. 

    // file.tellp(); // Program works correctly if I uncomment this. 
    // file.tellg(); // Program works correctly if I uncomment this. 

    file.read((char*)&buffer, 4); // position pointer should be at the beginning of the 2nd number 

    file.seekp(-4, ios::cur); // Since internal pointer is at the end of the file after the read(), I manually put it back to the beginning of the 2nd number. 

    buffer-=2000; 
    file.write((char*)&buffer,4); // Now, it should rewrite 2nd number with 2000. 

    file.close(); 
    return 0; 
} 
+0

我不明白你爲什麼seekp,讀的FP後應該是在第二號的開頭。 – Bond

+0

的確,我,我自己找不到解釋來做seekp。它應該正好在第二個數字的開頭,但是當我執行它時,它不起作用。但是,當我取消註釋seekg它的作品!我不知道爲什麼......很奇怪。 – atakan

回答

2

賓果!你已經偶然發現了C++語言的一個非常模糊,幾乎不成文和最好含糊的要求。我試圖爭論從G ++中刪除它,並寫了一個補丁來做到這一點,,但遇到了維護者溫暖的反應,這是在我顯示它可以完成沒有重新設計重新設計後被接受。

如果提供內存服務,C++規範提到文件流與C <stdio.h>流具有相同的語義,C規範說在讀取和寫入同一文件之間必須有seek

這裏是錯誤:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45708

討論#1:http://gcc.gnu.org/ml/libstdc++/2010-09/msg00079.html

討論#2:http://gcc.gnu.org/ml/libstdc++/2010-09/msg00104.html

編輯:我需要一個更好的記憶!實際上,2010年9月22日承諾的,進入GCC 4.6.0。未提交的其餘編輯與在I/O期間更改區域設置codecvt構面相關。

跟蹤接受改變的錯誤:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45628

+0

因此,在寫入和讀取之間添加tellg是一項要求?但爲什麼不沖洗工作? – atakan

+0

非常感謝。這些非常有用。 – atakan

+0

@user:是的,問題是解決文件*位置*,而不僅僅是沖洗。碰巧,'tellg'函數執行一次刷新,'flush'函數確定位置......並且無論如何這個要求是愚蠢的。我的補丁也消除了不必要的沖洗,IIRC。 – Potatoswatter