加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 当写入二进制文件时,`std :: ofstream :: write`有时会写入

发布时间:2020-12-16 09:57:18 所属栏目:百科 来源:网络整理
导读:我正在尝试将3D几何体写入二进制STL文件.以下是主程序的工作原理: ParseSTL stl();//generate the 3D modelstd::string outfname = "test.stl";std::ofstream outf(outfname,std::ios_base::out std::ios_base::binary);stl.writeBinarySTL(outf); 而STL的
我正在尝试将3D几何体写入二进制STL文件.以下是主程序的工作原理:

ParseSTL stl();
//generate the 3D model
std::string outfname = "test.stl";
std::ofstream outf(outfname,std::ios_base::out & std::ios_base::binary);
stl.writeBinarySTL(outf);

而STL的作者是:

void writeBinarySTL(std::ofstream &outf)
{
    char attr[2] = { 0 };
    char header[80] = { 0 };
    int count = 0;
    outf.write(header,80);
    //count += 80;
    //std::cout << "after header: file position: " << outf.tellp() << "  bytes written: " << count << "n";
    //if ((int)outf.tellp() != count)
    //    std::cout << "something is wrong!n";
    outf.write(reinterpret_cast<char *>(&facecount),sizeof(int));
    //count += sizeof(int);
    //std::cout << "after number of faces: file position: " << outf.tellp() << "  bytes written: " << count << "n";
    //if ((int)outf.tellp() != count)
    //    std::cout << "something is wrong!n";
    for (int i = 0; i < facecount; i++)
    {
        struct face{
            float n[3];
            float v[3][3];
        } f;
        for (int j = 0; j < 3; ++j)
            f.n[j] = (float) normals[i][j];
        for (int j = 0; j < 3; ++j)
            for (int k = 0; k < 3; ++k)
                f.v[j][k] = (float)vertices[faces[i][j]][k];
        outf.write(reinterpret_cast<char *>(&f),sizeof(f));
        //count += sizeof(f);
        //std::cout << "after struct: file position: " << outf.tellp() << "  bytes written: " << count << "n";
        //if ((int)outf.tellp() != count)
        //{
        //    std::cout << "something is wrong!n";
        //    break;
        //}
        outf.write(attr,2);
        //count += 2;
        //std::cout << "after attributes: file position: " << outf.tellp() << "  bytes written: " << count << "n";
        //if ((int)outf.tellp() != count)
        //{
        //    std::cout << "something is wrong!n";
        //    break;
        //}
    }
    //std::cout << "Bytes written: " << count << "n";
}

注释部分仅用于调试,facecount是存储多个三角形的ParseSTL类的成员,法线是存储所有面的法线的3D矢量的矢量,顶点是存储所有顶点的坐标的3D矢量的矢量.和faces是3个整数的向量,用于存储属于三角形的vrtices的索引.现在,如果我运行程序,这是我得到的输出:

Vertex count = 4243
Face count = 3168
Edge count = 0
after header: file position: 80  bytes written: 80
after number of faces: file position: 84  bytes written: 84
after struct: file position: 132  bytes written: 132
after attributes: file position: 134  bytes written: 134
...
after struct: file position: 532  bytes written: 532
after attributes: file position: 534  bytes written: 534
after struct: file position: 583  bytes written: 582
something is wrong!

所以,似乎行outf.write(reinterpret_cast< char *>(& f),sizeof(f));正在写1比它应该多的字节.这种漂移偶尔发生一次,最后,我得到一个158,896字节的文件,而不是一个158,484字节的文件.如果我在编写结构后添加了一个outf.seekp(count),那么最终的文件大小是正确的,但是一些浮点数没有正确写入(因此漂移并不总是在结构的末尾).

我想知道我做错了什么导致这个额外的字节被写入文件.哦,我正在使用Microsoft Visual Stusio Express 2013.

解决方法

这条线

std::ofstream outf(outfname,std::ios_base::out & std::ios_base::binary);

需要是

std::ofstream outf(outfname,std::ios_base::out | std::ios_base::binary);
                                              ^^^^^ The difference

可以通过省略std :: ios_base :: out标志来简化它(感谢@Blastfurnace提示).它还减少了这种错误蔓延的可能性.

std::ofstream outf(outfname,std::ios_base::binary);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读