代码之家  ›  专栏  ›  技术社区  ›  DaClown

读取二进制数据而不重新解释\u cast

  •  8
  • DaClown  · 技术社区  · 16 年前

    只是因为在我写程序读取二进制STL文件之前,我从未读过二进制文件。我用 ifstream

    主要功能:

    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)
    

    3 回复  |  直到 16 年前
        1
  •  7
  •   Community Mohan Dere    9 年前

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

    char* . (看见 casting via void* instead of using reinterpret_cast


    sizeof . 您只需初始化 static 类内的类外成员 .cpp (但是,编译器不知道 ::size 再也不能内联了)。
    或者,您可以将其编写为静态内联成员函数。在它的主体中,类类型被认为是完整的 sizeof (triangle) 这是允许的。或者你可以用 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
    };
    

    但是,第二种方法并不好,因为在添加成员时,您很容易忘记更新它。

        2
  •  2
  •   Alexander Gessler    16 年前

    __attribute__((packed))

        3
  •  -2
  •   Rune Aamodt    16 年前

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

    此外,在我看来,文件的内存映射是一种很少被人喜欢的技术。我不知道有任何标准/可移植库支持它,但如果你在Windows上,我建议你检查一下 this MSDN article