Прочитать строку и ее длину из бинарного файла, используя fread в C++

avatar
Bonje Fir
8 апреля 2018 в 05:53
1183
2
0

Ниже вы можете найти фрагмент кода, который я использовал для записи string_length с ним в двоичный файл, но код не работает должным образом. После того, как он пишет, я открыл выходной файл, и строка была там, но когда я читаю строку из файла, он читает строку частично. Кажется, что после чтения string_length указатель файла ищет больше, чем должен, а затем пропустил первые 8 символов строки!

#include <iostream>
#include <string>

FILE* file = nullptr;

bool open(std::string mode)
{
    errno_t err = fopen_s(&file, "test.code", mode.c_str());
    if (err == 0) return true;
    return false;
}

void close()
{
    std::fflush(file);
    std::fclose(file);
    file = nullptr;
}

int main()
{
    open("wb"); // open file in write binary mode

    std::string str = "blablaablablaa";

    auto sz = str.size();
    fwrite(&sz, sizeof sz, 1, file); // first write size of string
    fwrite(str.c_str(), sizeof(char), sz, file); // second write the string

    close(); // flush the file and close it

    open("rb"); // open file in read binary mode

    std::string retrived_str = "";

    sz = -1;
    fread(&sz, sizeof(size_t), 1, file); // it has the right value (i.e 14) but it seems it seeks 8 bytes more!
    retrived_str.resize(sz);
    fread(&retrived_str, sizeof(char), sz, file); // it missed the first 8 char

    close(); // flush the file and close it

    std::cout << retrived_str << std::endl;

    return 0;
}

PS: я удалил проверки в коде, чтобы сделать его более читабельным.

Источник
PaulMcKenzie
8 апреля 2018 в 06:02
0

&retrived_str -- указывает на объект, а не на базовый буфер, содержащий символы.

Ответы (2)

avatar
Miles Budnek
8 апреля 2018 в 06:05
2

Вы затираете объект retrieved_str с содержимым файла, а не читаете содержимое файла в буфер, управляемый retrieved_str.

fread(&retrived_str[0], 1, sz, file);

Или, если вы используете C++17 с неконстантным методом std::string::data:

fread(retrived_str.data(), 1, sz, file);
avatar
Mikhail
8 апреля 2018 в 06:13
1

Изменить

fread(&retrived_str, sizeof(char), sz, file); // it missed the first 8 char

Кому

fread((void*)( retrived_str.data()), sizeof(char), sz, file); // set the data rather than the object