我正在使用fstream将整数写入二进制文件。
int main(){
fstream f1;
int num = 2, num2 = 0;
f1.open("dat1", ios::app | ios::out | ios::in | ios::binary);
f1.write((char *)num, sizeof(int));
f1.seekp(0);
f1.read((char *)num2, sizeof(int));
cout << num2;
}
问题出在f1.write上。我可以写一个数组的二进制文件,但是当我尝试只编写一个int块时,它给了我一个错误:
Project.exe中0x522C7EA6(msvcp120d.dll)的未处理异常:0xC0000005:访问冲突读取位置0x00000002。
我不明白问题是什么。
答案 0 :(得分:5)
您需要将num
的地址转换为char*
,而不是num
。事实上,使用(char*)num
结果的行为是 undefined ,这解释了崩溃。
请改用f1.write((char *)&num, sizeof(num));
。同样更改f1.read
。
我还改变了sizeof
论点:我更喜欢这种风格,因为它可以防范类型变化。接下来,如果您在不同平台(例如Windows和Linux)中进行书写和阅读,则需要考虑 endianness 。
答案 1 :(得分:4)
你需要这个:
f1.write((char *)&num, sizeof(int));
f1.seekp(0);
f1.read((char *)&num2, sizeof(int));
write()
和read()
想要一个指向数据所在位置的指针。
int num = 2;
使用(char *)num
将num
转换为指向地址0x00000002
的指针。
此外,在处理二进制文件(测试除外)时,最好包含一个标题,该标题至少应包含以下内容:
A Magic Number(通常为4个字节),因此无论扩展名是什么,都可以确定或检查确切的文件类型。
版本号,可让您在未破坏当前格式的情况下扩展文件的格式和结构。
正如其他人已经说过的那样,Byte Order Mark将允许您在所有平台(Little-endian / Big-endian)上正确读取数据。
答案 2 :(得分:2)
该行实际上应该是:
f1.write((char *)&num, sizeof(int));
您需要地址作为write
功能的参数。
查看http://www.cplusplus.com/reference/ostream/ostream/write/。
答案 3 :(得分:0)
write
想要一个数组。这意味着起始地址。 (char *)num
这会将号码转换为地址,并指向您不想要的点。使用&num
获取num
的地址。也许用(char*)
进行演员表。