C++ 无法将动态数组写入文件
C++ Cannot write dynamic array to file
我正在尝试从浮点数的动态数组写入二进制文件。
这是我的代码:
FILE* file;
std::ofstream outStream;
file = fopen("mesh1.model", "w");
outStream = std::ofstream(file);
unsigned numTriangles;
float *vertices;
float *uvs;
unsigned degree = 0;
numTriangles = 2 * std::pow(4, degree); // numTriangles == 2 in this case
vertices = new float[9 * numTriangles];
uvs = new float[6 * numTriangles];
vertices[0] = -1.0f;
vertices[1] = 0.0f;
vertices[2] = 1.0f;
uvs[0] = 0.0f;
uvs[1] = 0.0f;
[....]
vertices[15] = 1.0f;
vertices[16] = 0.0f;
vertices[17] = -1.0f;
uvs[10] = 1.0f;
uvs[11] = 1.0f;
outStream.write((const char*)numTriangles, sizeof(numTriangles));
// Get runtime error on the line after this comment [access violation] (VS2013)
outStream.write((const char*)&(vertices), sizeof(float) * 9 * numTriangles);
outStream.write((const char*)&(uvs), sizeof(float) * 6 * numTriangles);
delete[] vertices;
delete[] uvs;
fclose(file);
file = fopen("mesh1.model", "r");
我查看了过去有类似问题的评论,但它们没有帮助。
其中一个使用了我尝试过的reinterpret_cast
但没有帮助。
这是你的罪魁祸首:
outStream.write((const char*)numTriangles, sizeof(numTriangles));
第一个参数应该是要写入的数据的地址,而不是数据本身!
将数据强制转换为预期的指针将关闭编译器,但会产生垃圾或核心转储(非法读取访问(。
您可能希望改用类似的东西:
outStream.write((const char *) & numTriangles, sizeof(numTriangles));
reinterpret_cast
并不是真的必要,除非你认为C++不够冗长。
ofstream
与流接口配合得很好,也就是说,当您想利用<<
运算符重载将对象的文本表示形式放入文件中时。
要编写纯二进制文件,ofstream
只是非常糟糕,因为它不提供透明的const void *
指针,并迫使您强制转换您尝试编写的每个数据块。
我的建议是坚持使用 STDIO 并使用 fwrite
,因为无论如何您都是从fopen
开始的。不那么冗长,而且也能完成工作。
编辑:
综上所述,正如cdhowie指出的那样,编写二进制数据的原始块可能会导致各种问题。
例如,假设您在具有不同大小的不同平台上重新编译代码unsigned
(这就像为 x64 而不是 x32 构建一样简单(。当新编译的可执行文件尝试读取数据时,数据会变成什么样?
如果您打算编写持久的代码,则可以考虑在可移植序列化代码上投入更多精力,该代码至少会使用独立于本机二进制表示形式的值(至少是固定大小的整数和浮点数以及字节序处理(。
另一种解决方案可能是编写文本数据并让像gzip
这样的专用库对其进行压缩。这也可能让你利用iostream
哲学,即以文本数据的形式编写对象。
你的三个write()
调用都是错误的。 但在我们进入之前,我们需要解决一件事:
切勿在C++中使用 C 样式转换。
C++有自己的、更具体的转换运算符,您应该始终使用它们。 在这种情况下,您希望使用 reinterpret_cast
.
第一种情况是错误的,因为您正在将非指针转换为指针。相反,您应该使用指向numTriangles
的指针。
outStream.write((const char*)numTriangles, sizeof(numTriangles));
// Should be this:
outStream.write(reinterpret_cast<const char *>(&numTriangles), sizeof(numTriangles));
在其他两种情况下,vertices
和 uvs
已经是指针并指向要保存的数据,因此此处不应使用 &
运算符:
outStream.write((const char*)&(vertices), sizeof(float) * 9 * numTriangles);
outStream.write((const char*)&(uvs), sizeof(float) * 6 * numTriangles);
// Should be this:
outStream.write(reinterpret_cast<const char *>(vertices), sizeof(float) * 9 * numTriangles);
outStream.write(reinterpret_cast<const char *>(uvs), sizeof(float) * 6 * numTriangles);
- 如何将内容数组写入文本文件?
- C++将文本文件中的数据读取到结构数组中
- 将值从二维数组输出到文本文件
- C++数据文件、数组和计算赋值
- 如何拆分文件中.txt字母并使用c ++使用数组进行扑克?
- 如何在 C++ 中从文件中读取字符数组(带有一些空格)
- 如何从txt文件中读取多个不同长度的数组?
- 保存/加载大量短数组到二进制文件
- 从二进制文件中读取整数数组
- 如何在 C++ 中将文件中的逗号分隔数字读取到数组中?
- C++ 使用存储在动态数组中的文本文件中的数据查找模式
- C++编程从外部文本文件定义数组大小
- 使用矢量将文本文件中的输入存储到 2D 数组中
- 如何将文本文件的特定行读取到 int 类型的数组中C++?
- 使用 stbi_write_png,如何将 0 和 1 的矩形字节数组转换为单色 png 文件?
- 将系数存储在头文件的数组中("does not name a type"错误)
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 从文件读取,并写入函数C++中的数组
- 如何使用QJSONARRAY在QT5(C )中解析JSON文件(数组)
- 从文件/数组C++聚合数据