【发布时间】:2019-12-09 12:05:40
【问题描述】:
所以,我所做的是创建一个结构数组。然后我将该数组写入二进制文件。我认为寻找文件中的第二个结构并覆盖它。然后我将文件读回一个单独的结构数组并将其打印到屏幕上。
写入完成后,文件大小从 24 字节变为 16 字节,第一个结构损坏,最后一个结构从文件中丢失。
这是我的代码:
#include<fstream>
#include<iostream>
using namespace std;
struct Point
{
int x, y;
};
void print(const Point& p)
{
cout << "(" << p.x << ", " << p.y << ")" << endl;
}
int main()
{
Point p[] = {{1, 2}, {3, 4}, {5, 6}};
for(auto a : p)
print(a);
// write array p to file
fstream f("points.dat", ios::binary | ios::out);
if(f)
{
f.write(reinterpret_cast<char*>(p), 3 * sizeof(Point));
f.close();
}
// read second struct from file and print it to screen
f.open("points.dat", ios::binary | ios::in);
if(f)
{
Point p;
f.seekg( 1 * sizeof(Point), ios::beg);
f.read(reinterpret_cast<char*>(&p), sizeof(Point));
f.close();
print(p);
}
// change ios::out to ios::ate and it works fine...
f.open("points.dat", ios::binary | ios::out);
if(f)
{
Point p ={-1, -2};
f.seekp(1 * sizeof(Point), ios::beg);
// attempting to overwrite the second struct in the file
// shrinks the file from 24 bytes to 16, losing the last
// struct in the file and causing the first struct to have
// 0's in it's fields.
f.write(reinterpret_cast<char*>(&p), sizeof(Point));
f.close();
}
Point q[3];
// read the file back into q and print q for testing.
f.open("points.dat", ios::binary | ios::in);
if(f)
{
// fails because the file is now only 16 bytes, instead of 24
f.read(reinterpret_cast<char*>(q), 3 * sizeof(Point));
f.close();
for(auto a : q)
print(a);
}
}
烦人的部分是当我将 ios::out 更改为 ios::ate 时,它工作得很好。
【问题讨论】:
-
虽然(IIRC)
ios::out(和其他标志)的使用是实现定义的,但我认为使用ios::out隐式添加ios::trunc和seekp被忽略。 (对于旧的fopen模式标志“w”当然是正确的。)