簡體   English   中英

部分寫入文件-C ++

[英]Partial write to a file - C++

我正在用C ++處理VS2010。

我有一堂課。 Room具有x和ay屬性,然后具有許多其他屬性。

我有一個名為Rooms.txt的文件,其中包含“ Room”對象的一堆屬性。 它使用一種自定義語法,因此一個條目可能看起來像這樣:

$ x $ y $ name $ size $ type $ state $ EOL @ $

因此,我可以進行以下工作:玩家輸入X和Y坐標,並將文本文件中相應條目的值提供給Room對象。

然后,我想做的就是允許播放器更改其中一些變量,並將其寫回到文件中,但是我還不太清楚該怎么做。 到目前為止,這是我最大的努力:

    ifstream inRoom;
ofstream outRoom;
string path = saveRoot;
path.append(ModLoad); // the last two lines get the path for the file to be read/written

inRoom.open(path);
//outRoom.open(path);
string temp;
string temp2;
if(inRoom.bad()){
    cout << "ERROR: Bad save!";
}
while(inRoom.good()){
    temp2 = temp;
    getline(inRoom,temp,'$');
    cout << temp <<inRoom.tellg();
    if ((atoi(temp2.c_str())==myPlayer.X)&&(atoi(temp.c_str())==myPlayer.Y)){
        int seek = inRoom.tellg();
        inRoom.close();
        cout << "Opening " << path << "for writing \n";
        outRoom.open(path);
        outRoom.seekp(seek);
        outRoom.write("HELLO!", 6);
        outRoom.close();
    }
}
inRoom.close();

另外,我需要覆蓋值,而不是插入新數據。 有什么想法嗎?

您選擇了錯誤的格式。 為了使覆蓋生效,您需要使用固定寬度的格式 因此,無論如何,每個房間占用文件中相同數量的字節。 這樣,當您覆蓋一個房間時,您可以將新房間放在舊房間的頂部,而不必擔心您是否將整個文件插入幾個字節或從文件中刪除幾個字節。

如果您有一個公式可以直接從x和y坐標告訴文件中房間的位置,那么它也確實會讓您的生活更輕松。 您不必遍歷文件尋找合適的空間,而可以立即尋找合適的位置。

僅重寫文件中的某些數據需要兩件事:

  • 您必須知道文件中開始寫入的位置。 然后,您可以像以前一樣使用seekp()轉到該位置。
  • 更棘手的是:寫入的數據必須與字節數完全相同。 否則,您將覆蓋以下數據或留下一些舊字節,使文件結構混亂。

要打開文件以重寫零件,請使用

file.open(filename, ios::binary|ios::in|ios::out|ios::ate);
file.seekg(0);
// or go to the position to read your data directly
// store that position using tellg()
// read data
// restore position using tellp()
// write data (in exact same length)

我記得這里的技巧是在文件ios::ate結尾打開文件。 否則,您可能會(部分)丟失文件的內容。

請記住,您使用的是C ++,因此您必須考慮對象。 我要做的是:

  • 通過重載>>和<<運算符將序列化添加到您的Room類中
  • 在執行開始時將條目列表讀取到內存中(例如,使用std :: vector)
  • 當用戶輸入X和Y時,在存儲器中存儲的條目列表中查找對應的條目並顯示它
  • 如果用戶修改了某些內容,請用新的內容替換內存中的現有條目
  • 將整個條目列表寫回到文件中,以完全替換其內容

這是一個快速而骯臟的代碼草案,只是為了說明這個想法:

#include <vector>
#include <iostream>
#include <fstream>
#include <iterator>

class Room
{
    public:
        int x;
        int y;
        std::string a;
        std::string b;

    private:
        friend std::ostream& operator <<(std::ostream& os, const Room& r);
        friend std::istream& operator >>(std::istream& is, Room& r);

};

std::ostream& operator <<(std::ostream &os, const Room& r)
{
    return os << r.x << r.y << r.a << r.b;
}

std::istream& operator >>(std::istream& is, Room& r)
{
    return is >> r.x >> r.y >> r.a >> r.b;
}


int main()
{
    std::vector<Room> roomList;

    // read the list
    ifstream in("out.txt");
    istream_iterator<Room> ii(in), iieof;
    copy(ii, iieof, back_inserter(roomList));
    in.close();

    // do something with your data
    // ...

    // save the modified list back
    ofstream out("out.txt");
    ostream_iterator<Room> oi(out, "\n");
    copy(roomList.begin(), roomList.end(), oi);
    out.close();

    return 0;    
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM