У меня есть структура. Я хотел бы иметь массив в этой структуре, а затем записать его в двоичный файл, а затем прочитать его. Однако этот массив должен быть размещен динамически. Я не знаю, как мне к этому подойти. Мое текущее предположение таково:

Я определяю и записываю структуру в файл следующим образом:

struct map {
    int *tiles;
};

int main() {

    map sample;

    sample.tiles = new int[2];

    sample.tiles[0]=1;
    sample.tiles[1]=2;

    ofstream file("sample.data", ios::binary);

    file.write((char *)&sample, sizeof(sample));

    file.close();

    return 0;
}

Затем прочтите это так в другой программе:

map test;
ifstream file("sample.data", ios::binary);
file.read((char *)&test, sizeof(test));

Когда я хочу проверить результаты с

cout << test.tiles[0];

Я получаю странно огромное число, но явно не то, которое я изначально записал в файл.

Как правильно это сделать? Как я могу прочитать массив, не зная его размера?

0
Letokteren 27 Ноя 2016 в 19:13

2 ответа

Лучший ответ
file.write((char *)&sample, sizeof(sample));

Это записывает в файл следующую структуру:

struct map {
    int *tiles;
};

То есть структура, содержащая единственный указатель. Указатель - это адрес в памяти. Итак, в конечном итоге вы записываете в файл один бессмысленный, необработанный адрес памяти.

Что, очевидно, совершенно бесполезно, когда его прочитают позже. Вы не записали ни одно из своих целых чисел в свой файл, только их адрес в памяти, в программе, которая давно завершилась.

Для того, чтобы сделать это правильно, вам необходимо:

  1. Запишите, на сколько int - эгеров указывает указатель tiles.

  2. fwrite() не сама структура, а целые числа, на которые указывает указатель tiles.

Вам также нужно будет записать в файл, сколько целых чисел содержится в этом массиве. Если файл содержит только эти целые числа, в этом нет необходимости, поскольку вы можете просто прочитать все содержимое файла. Но, если вы ожидаете записать некоторые дополнительные данные в файл, очевидно, что становится необходимым также записать размер записанного массива в самом файле, чтобы можно было выяснить, сколько целых чисел существует при их чтении. назад. Самый простой способ сделать это - записать один int, сначала размер массива, а затем содержимое самого массива. И сделайте обратный процесс, когда все прочитаете обратно.

3
Sam Varshavchik 27 Ноя 2016 в 17:13

Ваш объект sample содержит указатель tiles, и это значение указателя, которое вы записываете в файл. Вы хотите написать то, на что указывает указатель. В вашем примере вы хотите сделать file.write(sample.tiles, 2*sizeof(*sample.tiles));. Это 2*, потому что вы сделали new int[2]. В общем, вы также хотите сохранить размер (в данном случае 2) в файле, чтобы знать, сколько целых чисел нужно прочитать обратно. В этом простом случае вы можете вывести 2 из размера файла.

1
Waxrat 27 Ноя 2016 в 16:19