将字符串向量写入二进制文件时出现问题

时间:2018-11-26 01:24:31

标签: c++ serialization ifstream ofstream

我正在使用ofstream / ifstream将数据序列化为二进制文件。数据分为两个字符串向量,一个用于数据名称,另一个用于数据值onActivityCreated()std::vector<std::string> dataNames

我正在使用此功能写数据:

std::vector<std::string> dataValues

并使用以下内容进行阅读:

void Data::SaveData(std::string path)
{
    std::ofstream outfile(path, std::ofstream::binary);
    outfile.write(reinterpret_cast<const char *>(&dataNames[0]), dataNames.size() * sizeof(std::string));
    outfile.write(reinterpret_cast<const char *>(&dataValues[0]), dataValues.size() * sizeof(std::string));
    outfile.close();
}

有效。我可以正确地读写它。 除了,如果dataNames或dataValues中的任何字符串具有16个字符或更多。

使用少于16个字符的字符串的数据示例:

bool Data::LoadData(std::string path)
{
    bool ret = false;

    std::ifstream file(path, std::ifstream::in | std::ifstream::binary);
    if (file.is_open())
    {
        // get length of file:
        file.seekg(0, file.end);
        int length = file.tellg();
        file.seekg(0, file.beg);

        char * buffer = new char[length];
        file.read(buffer, length);

        if (file)
        {
            char* cursor = buffer;
            uint32_t bytes = length / 2;
            dataNames.resize(bytes / sizeof(std::string));
            memcpy(dataNames.data(), cursor, bytes);

            cursor += bytes;
            dataValues.resize(bytes / sizeof(std::string));
            memcpy(dataValues.data(), cursor, bytes);

            delete[] buffer;
            buffer = nullptr;
        }

        file.close();
        ret = true;
    }

    return ret;
}

data 15 chars

使用超过16个字符的字符串的数据示例:

dataNames[0] = "Type"
dataNames[1] = "GameObjectCount"

dataValues[0] = "Scene"
dataValues[1] = "5"

data 16 chars

在这里您可以看到单词“ GameObjectsCount”没有出现,并且显示了扩展字符。 读取此文件时,字符串无效。有时是空的,有时说“读取字符串的字符时出错”,有时是一个随机字母...

有什么主意吗?

1 个答案:

答案 0 :(得分:0)

以上述方式重新解释{"characters":[{"name":"Netherfry","realm":"Bleeding Hollow","battlegroup":"Ruin","class":5,"race":8,"gender":0,"level":5,"achievementPoints":0,"thumbnail":"bleeding-hollow/27/163571995-avatar.jpg","lastModified":0},{"name":"Netherwarz","realm":"Darkspear","battlegroup":"Cyclone","class":9,"race":5,"gender":0,"level":5,"achievementPoints":0,"thumbnail":"darkspear/130/86434434-avatar.jpg","guild":"GeekyGaming","guildRealm":"Darkspear","lastModified":0},{"name":"Hailnether","realm":"Akama","battlegroup":"Reckoning","class":1,"race":2,"gender":0,"level":2,"achievementPoints":0,"thumbnail":"akama/235/95051243-avatar.jpg","lastModified":0},{"name":"Hailnether","realm":"Khaz Modan","battlegroup":"Cyclone","class":2,"race":10,"gender":0,"level":1,"achievementPoints":0,"thumbnail":"khaz-modan/53/101812021-avatar.jpg","lastModified":0},{"name":"Hailne6EA459","realm":"Greymane","battlegroup":"Shadowburn","class":5,"race":11,"gender":0,"level":0,"achievementPoints":0,"thumbnail":"greymane/89/91137113-avatar.jpg","lastModified":0},{"name":"Netherdrew","realm":"Bleeding Hollow","battlegroup":"Ruin","class":11,"race":8,"gender":0,"level":91,"achievementPoints":1470,"thumbnail":"bleeding-hollow/134/156092806-avatar.jpg","spec":{"name":"Guardian","role":"TANK","backgroundImage":"bg-druid-bear","icon":"ability_racial_bearform","description":"Takes on the form of a mighty bear to absorb damage and protect allies.\r\n\r\nPreferred Weapon: Staff, Polearm","order":2},"guild":"EndlessVoid","guildRealm":"Bleeding Hollow","lastModified":1429907056000},{"name":"Hailnether","realm":"Wyrmrest Accord","battlegroup":"Cyclone","class":3,"race":4,"gender":0,"level":3,"achievementPoints":0,"thumbnail":"wyrmrest-accord/146/109003154-avatar.jpg","lastModified":0},{"name":"Nethermonk","realm":"Bleeding Hollow","battlegroup":"Ruin","class":10,"race":10,"gender":0,"level":1,"achievementPoints":0,"thumbnail":"bleeding-hollow/13/157523981-avatar.jpg","lastModified":0},{"name":"Netherwraith","realm":"Bleeding Hollow","battlegroup":"Ruin","class":9,"race":10,"gender":0,"level":16,"achievementPoints":1305,"thumbnail":"bleeding-hollow/72/157163336-avatar.jpg","spec":{"name":"Affliction","role":"DPS","backgroundImage":"bg-warlock-affliction","icon":"spell_shadow_deathcoil","description":"A master of shadow magic who specializes in drains and damage-over-time spells.\r\n\r\nPreferred Weapon: Staff, Wand, Dagger, Sword","order":0},"lastModified":1411674035000},{"name":"Netherhunt","realm":"Bleeding Hollow","battlegroup":"Ruin","class":3,"race":2,"gender":0,"level":11,"achievementPoints":1380,"thumbnail":"bleeding-hollow/245/163559157-avatar.jpg","spec":{"name":"Marksmanship","role":"DPS","backgroundImage":"bg-hunter-marksman","icon":"ability_hunter_focusedaim","description":"A master sharpshooter who excels in bringing down enemies from afar.\r\n\r\nPreferred Weapon: Bow, Crossbow, Gun","order":1},"guild":"EndlessVoid","guildRealm":"Bleeding Hollow","lastModified":1425762452000},{"name":"Netherlock","realm":"Cho'gall","battlegroup":"Vindication","class":9,"race":10,"gender":0,"level":16,"achievementPoints":0,"thumbnail":"chogall/88/110060376-avatar.jpg","guild":"Mindless","guildRealm":"Cho'gall","lastModified":0},{"name":"Biìzzard","realm":"Bloodhoof","battlegroup":"Ruin","class":1,"race":2,"gender":0,"level":1,"achievementPoints":0,"thumbnail":"bloodhoof/42/108061994-avatar.jpg","lastModified":0},{"name":"Netherman","realm":"Cho'gall","battlegroup":"Vindication","class":3,"race":10,"gender":0,"level":20,"achievementPoints":1370,"thumbnail":"chogall/223/109983711-avatar.jpg","spec":{"name":"Marksmanship","role":"DPS","backgroundImage":"bg-hunter-marksman","icon":"ability_hunter_focusedaim","description":"A master sharpshooter who excels in bringing down enemies from afar.\r\n\r\nPreferred Weapon: Bow, Crossbow, Gun","order":1},"guild":"IliilBARCODEliilI","guildRealm":"Cho'gall","lastModified":1425698021000},{"name":"Yoursbaby","realm":"Moon Guard","battlegroup":"Reckoning","class":5,"race":1,"gender":1,"level":1,"achievementPoints":0,"thumbnail":"moon-guard/213/116473301-avatar.jpg","lastModified":0},{"name":"Hailne652387","realm":"Bladefist","battlegroup":"Vengeance","class":5,"race":11,"gender":0,"level":2,"achievementPoints":0,"thumbnail":"bladefist/135/107291527-avatar.jpg","lastModified":0},{"name":"Aazzdf","realm":"Bleeding Hollow","battlegroup":"Ruin","class":1,"race":2,"gender":1,"level":1,"achievementPoints":0,"thumbnail":"bleeding-hollow/145/164662417-avatar.jpg","lastModified":0},{"name":"Nethersquad","realm":"Bleeding Hollow","battlegroup":"Ruin","class":10,"race":10,"gender":0,"level":0,"achievementPoints":0,"thumbnail":"bleeding-hollow/36/157524004-avatar.jpg","lastModified":0},{"name":"Darknether","realm":"Bleeding Hollow","battlegroup":"Ruin","class":6,"race":10,"gender":0,"level":62,"achievementPoints":1380,"thumbnail":"bleeding-hollow/118/156625270-avatar.jpg","spec":{"name":"Unholy","role":"DPS","backgroundImage":"bg-deathknight-unholy","icon":"spell_deathknight_unholypresence","description":"A master of death and decay, spreading infection and controlling undead minions to do her bidding.\r\n\r\nPreferred Weapon: Two-Handed Axe, Mace, Sword","order":2},"lastModified":1425841594000},{"name":"Lpeodke","realm":"Hellscream","battlegroup":"Rampage","class":5,"race":1,"gender":1,"level":1,"achievementPoints":0,"thumbnail":"hellscream/115/106721395-avatar.jpg","lastModified":0}]}` 是不正确的。

vector

您不知道 outfile.write(reinterpret_cast<const char *>(&dataNames[0]), dataNames.size() * sizeof(std::string)); 是如何在堆上存储数据的,等等,并且您不能假设您可以盲目地投射指针并将看到的内容写为文件。一种序列化数据的方法。此外,std :: string不一定 输入大小的就地字符数组。更有可能是指向堆上对象的指针。

因此,如果要序列化vector或其他stdlib类型的数据,则需要编写一个函数来实现此目的,方法是对项目进行迭代并以适当分隔的方式进行写入。