Чтение двоичного файла С++ в структуру

Я написал двоичный файл, используя следующую структуру:

struct block{
char data[32];
};

поэтому в итоге я получаю большой двоичный файл, полный char [32]. Данные форматируются в определенных положениях, поэтому захват определенных фрагментов информации не составляет труда. Однако я попытался прочитать файл следующим образом:

int lines=0;
std::ifstream inputFile("file.bin",std::ios::binary);

while (!inputFile.eof())
{
 inputFile.read(blocks[lines].data, sizeof(block));
 lines++;
}

inputFile.close();
lines--;

и затем отображать его следующим образом:

std::cout<<"block 1: "<
<p> Я думал, что block [i].data должен просто дать мне char [32], который принадлежит индексу i, но вместо этого дает мне каждый элемент данных в структуре из этого индекса в конец структуры. Я уверен, что это мое непонимание того, как это работает. Мой вопрос: как мне просто получить char [32], представленный блоками [i].data?</p>
3 ответа

Проблема заключается в выводе вывода std::cout. Когда вы пытаетесь вывести blocks[0].data, какой operator<< получает не массив из 32 символов, а указатель на первый символ. Это интерпретируется как указатель на строку C, поэтому он выводит все символы, найденные в памяти, туда, пока не найдет '\0'. Поскольку каждый элемент массива содержит только соответствующие символы из файла, выводятся все символы файла (если в файле нет '\0', тогда выход останавливается). Кроме того, вам кажется (un-) повезло, что '\0' следует за вашими данными в памяти, поэтому выход останавливается там (вместо того, чтобы продолжать выводить все, что есть в памяти, и, возможно, давать ошибку сегментации, когда конец из памяти процесса ".

Чтобы просто вывести 32 символа в качестве символов, используйте std::cout.write(blocks[0].data,32). В противном случае, чтобы выводить их как ints, просто перебирайте их и конвертируйте их в int:

for (int i = 0; i < 32; ++i)
 std::cout << static_cast<int>(blocks[0].data[i]) << ' ';
</int>

Конечно, вы можете использовать все манипуляторы потока для получения чисел в std::setfill вам виде (например, std::hex для шестнадцатеричного вывода и/или std::setw и std::setfill чтобы получить номера фиксированной ширины).


Ваш раздел ввода необходимо изменить:

while (inputFile.read(blocks[lines].data, sizeof(block))
{
 lines++;
}

Причина заключается в том, что условие EOF не определяется не только после возникновения операции чтения. Одним из побочных эффектов использования EOF-проверки является то, что дополнительная строка может быть прочитана.


std::cout<<"block 1: "<
<p> Вы отправляете <code>char[] в поток, который получает повышение до char*, поэтому он считает строку с завершающим символом NULL и пытается отобразить ее как таковую. Трудно сказать, что вам нужно, но это покажет его в hexidecimal:

std::cout << std::setfill('0') << std::hex;
for(int i=0; i<25; ++i)
 std::cout << std::setw(2) << blocks[0].data[i];
std::cout << std::setfill(' ') << std::dec;

licensed under cc by-sa 3.0 with attribution.