首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不使用reinterpret_cast读取二进制数据

不使用reinterpret_cast读取二进制数据
EN

Stack Overflow用户
提问于 2010-03-01 22:57:56
回答 3查看 5.2K关注 0票数 9

只是因为在我写了一个读取二进制STL文件的程序之前,我从未读过二进制文件。我使用ifstream的read成员,该成员接受一个char* a参数。为了将我的结构转换为char*,我使用了reinterpret_cast。但就我记忆所及,我读过的每一本关于C++的书都说过“除非迫不得已,不要使用reinterpret_cast”。什么是读取二进制数据的更好的方法,不一定是直接的,但最终进入一个结构,而不是reinterpret_cast?

主要功能:

代码语言:javascript
复制
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

和三角形结构

代码语言:javascript
复制
//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)

(额外的问题:#杂注包(1)不适用于cygwin g++-4。如何确定结构的大小?)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-01 23:07:20

好吧,这段代码看起来没问题。您甚至关心填充问题。我不明白你怎么能在这里避免选角。您可以执行以下操作:

代码语言:javascript
复制
static_cast<char*>(static_cast<void*>(t))

但实际上,我不会在我的代码中这样做。这只是一种更繁琐的方式,直接对char*执行reinterpret_cast。(参见casting via void* instead of using reinterpret_cast )。

结构的大小可以使用sizeof来确定。您只需在.cpp内的类之外初始化static成员(但是,编译器将不再知道::size的值,也不能内联它)。

或者,您可以将其编写为静态内联成员函数。在它的主体中,类类型被认为是完整的,并且允许使用sizeof (triangle)。或者,您可以像在注释中一样使用sizeof,但使用类型而不是成员(仅在C++0x中才允许以这种方式引用非静态成员):

代码语言:javascript
复制
//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
};

然而,第二种方法并不好用,因为当你添加一个成员时,你很容易忘记更新它。

票数 7
EN

Stack Overflow用户

发布于 2010-03-01 23:07:31

额外的问题:看看__attribute__((packed))

票数 2
EN

Stack Overflow用户

发布于 2010-03-01 23:07:53

将流用于文件i/o (特别是二进制)在我看来是令人讨厌的。如果我是你的话,我宁愿只使用像fopen和fread这样的老C函数。

此外,文件的内存映射是一种被给予太少关爱的技术,IMO。我不知道有什么标准的/可移植的库支持它,但是如果你使用的是Windows,我建议你检查一下this MSDN article

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2356636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档