Чтение двоичных данных без reinterpret_cast

Просто, потому что я никогда не читал двоичные файлы, прежде чем я записал программу, которая читает двоичные файлы STL. Я использую ifstreams участник чтения, который берет символ* параметр. Для кастинга моей структуры к символу*, я использую reinterpret_cast. Но насколько я помню каждую книгу о C++, который я считал, сказал, что что-то как "не использует reinterpret_cast кроме Вас, имеют к". Каковы были бы считанные двоичные данные лучшего пути, не обязательно прямые, но наконец в структуру и без reinterpret_cast?

Основная функция:

std::ifstream in (cmdline[1].c_str(), std::ios::binary);

in.seekg(80, std::ifstream::beg); //skip header

int numTriangle;
in.read (reinterpret_cast<char*>(&numTriangle), sizeof(int)); //determine number of triangles
//create triangle data type and read data
triangle* t = new triangle();
for (int i = 0; i < numTriangle; ++i)  {
    in.read(reinterpret_cast<char*>(t), triangle::size);
    std::cout << *t;  // there's an opertor<< for triangle
}
delete t;

in.close(); //close file read from

И треугольная структура

//attempt to get the right size of a class without structure padding
#pragma pack(push)
#pragma pack(1)

//standard STL triangle data structure
struct triangle {
public:
    float n[3]; //normals, 4*3=12 bytes

    float x[3]; //first point of the triangle, 4*3=12 bytes
    float y[3]; //second point of the triangle, 4*3=12 bytes
    float z[3]; //third point of the triangle, 4*3=12 bytes

    long int a; //attributes, 2 bytes

    static const int size = 12+12+12+12+2; //sum of member variables
    //static const int size = sizeof(n) + sizeof(x) + sizeof(y) + sizeof(z) + sizeof(a);
};
#pragma pack(pop)

(Дополнительный вопрос: пакет #pragma (1) не работает с cygwins g ++-4. Как я могу определить размер структуры?)

8
задан DaClown 1 March 2010 в 14:57
поделиться

3 ответа

Что ж, этот код выглядит нормально.Вы даже заботитесь о проблеме заполнения. Не понимаю, как здесь избежать кастинга. Вы можете сделать такую ​​последовательность:

static_cast<char*>(static_cast<void*>(t))

Но на самом деле я не делаю этого в своем коде. Это просто более шумный способ выполнить прямое преобразование reinterpret_cast в char * . (См. приведение типов через void * вместо использования reinterpret_cast ).


Размер структуры можно определить с помощью sizeof . Вам просто нужно инициализировать член static вне класса внутри .cpp (однако тогда компилятор не знает значение :: size больше и не могу встроить его).
Кроме того, вы можете написать его как статическую встроенную функцию-член. В его теле тип класса считается завершенным и допускается sizeof (треугольник) . Или вы можете просто использовать sizeof , как указано в комментарии, но использовать тип, а не члены (обращение к нестатическим членам таким образом разрешено только в C ++ 0x):

//standard STL triangle data structure
struct triangle {
public:
    float n[3]; //normals, 4*3=12 bytes

    float x[3]; //first point of the triangle, 4*3=12 bytes
    float y[3]; //second point of the triangle, 4*3=12 bytes
    float z[3]; //third point of the triangle, 4*3=12 bytes

    long int a; //attributes, 2 bytes

    static int size() { return sizeof(triangle); } // this way
    static const int size = sizeof(float[3])*4 + sizeof(long int); // or this way
};

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

6
ответ дан 5 December 2019 в 22:17
поделиться

Дополнительный вопрос: взгляните на __ attribute __ ((pack)) .

2
ответ дан 5 December 2019 в 22:17
поделиться

Использование потоков для ввода-вывода файлов (особенно двоичных), на мой взгляд, просто отвратительно. На вашем месте я бы предпочел просто использовать старые функции Си, такие как fopen и fread.

Кроме того, отображение файла в память - это техника, которой уделяется слишком мало внимания, IMO. Я не знаю никаких стандартных/портативных библиотек, которые поддерживают ее, но если вы работаете под Windows, я советую посмотреть эту статью MSDN

-2
ответ дан 5 December 2019 в 22:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: