【问题标题】:Why do structs disappear in my file when i write to it为什么当我写入文件时结构会在我的文件中消失
【发布时间】:2018-03-23 03:16:37
【问题描述】:

每当我将struct 写入二进制文件时,它之后的任何structs 都会消失,尽管之前写入的任何structs 仍然存在。

我以二进制输出模式打开文件流,而我的structs 仅包含原始数据类型。

我还确保为每个操作创建单独的文件流。

输出:

create players
765
51

save 1
765

save 2
765
51

** struct 定义**

struct player{
    int UUID;
};

保存structs的功能

//updates player information in the player database
bool savePlayer(player playerData){
    //count how manny playrs are in file
    // Create our objects.
    fstream countstream;
    int count = 0;
    countstream.open ("player.bin", ios::binary | ios::in);
    if(countstream.is_open()){
        countstream.seekg(0, ios::end); //set position to end
        count = countstream.tellg()/sizeof(player);
        //retuns number of players in file by getting
        //the index of the position and dividing it by the size of each player
        //no loops required :D
    }
    countstream.close();

    bool found = false;

    //if file is not empty,look through it
    if(count > 0){
        player playerTable[count];
        fstream readstream;
        readstream.open ("player.bin", ios::binary | ios::in);
        //build table
        for(int i = 0; i < count; i++){
            readstream.seekg(i, ios::beg); //set position to end
            readstream.read(reinterpret_cast <char *> (&playerTable[i]), 
                            sizeof(player));
            readstream.close();
        }

        //check table
        for(int i = 0; i < count; i++){
            if(playerTable[i].UUID == playerData.UUID){
                found = true;
                playerTable[i] = playerData;
            }
        }

        //write table back to file
        if(found){
            fstream writestream; //create writestream
            writestream.open ("player.bin", ios::binary | ios::out);
            for(int i = 0; i < count; i++){
                writestream.seekg(i, ios::beg); //set position to player
                writestream.write(reinterpret_cast <char *> (&playerTable[i]), 
                                  sizeof(player));
                if(!writestream.fail()){
                    writestream.close();
                    return true;
                }
                else{
                    writestream.close();
                    return false;
                }
                readstream.close();
            }
        }
    }

    //append if not found
    if(!found){
        fstream appendstream;
        appendstream.open ("player.bin", ios::binary | ios::out | 
                           ios::app);
        appendstream.write(reinterpret_cast <char *> (&playerData), 
                           sizeof(player));
        appendstream.close();
        if(!appendstream.fail()){
            appendstream.close();
            return true;
        }
        else{
            appendstream.close();

            return false;
        }
    }
    return false;
}

任何建议将不胜感激。

【问题讨论】:

  • 在readstream 循环中关闭循环内的文件,因此您只读取一行
  • 我的结构只包含原始数据类型——眼见为实。请发帖player。
  • 仅供参考:即使您解决了上述所有问题,这也仅适用于具有与最初编写时相同的类型大小和字节顺序的操作系统和编译器。你真的应该使用像 USCILab 的 Cereal 这样的轻量级工具来为你序列化结构:github.com/USCiLab/cereal
  • 也没有必要先得到计数。只需使用while (readstream.read(...)) 继续阅读,直到读完为止。
  • 应该是readstream.seekg(i * sizeof(player), ios::beg);。但是你根本不需要寻找,每个read()都从前一个完成的地方开始。

标签: c++ struct


【解决方案1】:

你让这件事变得比必要的困难得多。您不需要将所有数据读入数组。您可以将每个项目读入一个变量,并检查它是否是您要替换的那个。通过以读写模式打开文件,您可以在读取文件时简单地覆盖文件中的该条目。

bool savePlayer(player playerData){

    player curPlayer;
    fstream stream;
    stream.open ("player.bin", ios::binary | ios::in | ios::out);
    while(stream.read(reinterpret_cast<char*>(&curPlayer), sizeof(curPlayer))){
        if (curPlayer.UUID == playerData.UUID) {
            stream.seekg(-(sizeof curPlayer), ios::cur); // back up to location of current player
            break;
        }
    }
    stream.write(reinterpret_cast<char*>(&playerData), sizeof playerData);
    stream.close();
    return false;
}

【讨论】:

  • 当文件不存在时,它不会创建文件。我不认为我可以在输入和输出模式下使用相同的流。我知道从技术上讲它应该可以工作,但是当我尝试它时它什么也没做
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
  • 2021-05-30
  • 1970-01-01
相关资源
最近更新 更多