Проблема записи векторов строк в двоичный файл - PullRequest
0 голосов
/ 26 ноября 2018

Я сериализирую данные в двоичный файл с использованием ofstream / ifstream.Данные разделены на 2 вектора строк, один для имен данных и другой для значений данных, 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();
}

И читая это используя:

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;
}

Это работает.Я могу написать и прочитать это правильно. За исключением , если какая-либо из строк в dataNames или dataValues ​​имеет 16 или более символов.

Пример данных, использующих строки с менее чем 16 символами:

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

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

данные 15 символов

Пример данных с использованием строк с более чем 16 символами:

dataNames[0] = "Type"
dataNames[1] = "GameObjectsCount"   //Added a s. Now have 16 chars

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

данные 16 символов

Здесь выможно увидеть, что слово «GameObjectsCount» не появляется и отображаются посторонние символы.При чтении этого файла строка недопустима.Иногда оно пустое, иногда говорит «Ошибка чтения символов строки», иногда это буквенное имя ...

Есть идеи?

1 Ответ

0 голосов
/ 26 ноября 2018

Неправильно интерпретировать vector указанным выше способом.

 outfile.write(reinterpret_cast<const char *>(&dataNames[0]), dataNames.size() * sizeof(std::string));

Вы не знаете, как vector хранит данные (в куче и т. Д.),и вы не можете предполагать, что можете слепо привести указатель и записать в файл все, что вы видите, в качестве метода сериализации данных.Кроме того, std :: string не является обязательно массивом символов на месте размера входных данных.Скорее всего, это указатель на объект в куче.

Итак, если вы хотите сериализовать данные в vector или другом типе stdlib, вам нужно написать функцию, чтобы сделать это вручную с помощьюперебирая элементы и записывая их правильно разделенными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...