英文:
Reading a binary file using C++
问题
我正在执行将类的内容写入二进制文件,然后读取并显示它们的简单任务。我使用以下代码实现:
```cpp
class Matrix{
public:
vector<vector<float>> Mat;
int d;
};
int main()
{
Matrix M, M1;
for(int i=0;i<10;i++)
{
vector<float> row;
for(int j=0;j<20;j++)
{
row.push_back(i+j);
}
M.Mat.push_back(row);
}
M.d=24;
ofstream file("Data_for_Matrix2.bin", ios::binary|ios::trunc);
if(!file.is_open()) cout<<"文件错误!";
file.write((char*)&M, sizeof(M));
file.close();
ifstream file2("Data_for_Matrix2.bin", ios::binary|ios::ate);
if(!file2.is_open()) cout<<"文件未打开!";
file2.seekg(0);
file2.read((char*)&M1, sizeof(M1));
cout<<"\n整数数据成员: "<<M1.d;
cout<<"\n矩阵数据成员: \n";
for(int i=0;i<10;i++)
{
for(int j=0;j<20;j++)
{
cout<<M1.Mat[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}
这会产生所需的输出。然而,当我单独(使用不同的 .cpp 文件)尝试使用以下代码读取上述创建的文件时,它不起作用。
class Matrix{
public:
vector<vector<float>> Mat;
int d;
};
int main()
{
Matrix M1;
ifstream file2("Data_for_Matrix2.bin", ios::in|ios::binary);
if(!file2.is_open()) cout<<"文件未打开!";
file2.seekg(0);
file2.read((char*)&M1, sizeof(M1));
cout<<"\n整数数据成员: "<<M1.d;
cout<<"\n矩阵数据成员: \n";
for(int i=0;i<10;i++)
{
for(int j=0;j<20;j++)
{
cout<<M1.Mat[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}
它生成的输出是:
整数数据成员: 24
矩阵数据成员:
进程在不打印矩阵内容的情况下退出。我无法确定问题出在哪里。可能出了什么问题?
<details>
<summary>英文:</summary>
I am performing this simple task of writing into a binary file the contents of a class followed by reading and displaying them. I achieve that using the follwing code:
class Matrix{
public:
vector<vector<float>> Mat;
int d;
};
int main()
{
Matrix M, M1;
for(int i=0;i<10;i++)
{
vector<float> row;
for(int j=0;j<20;j++)
{
row.push_back(i+j);
}
M.Mat.push_back(row);
}
M.d=24;
ofstream file("Data_for_Matrix2.bin", ios::binary|ios::trunc);
if(!file.is_open()) cout<<"\nfile error!!";
file.write((char*)&M, sizeof(M));
file.close();
ifstream file2("Data_for_Matrix2.bin", ios::binary|ios::ate);
if(!file2.is_open()) cout<<"\nFile not open!";
file2.seekg(0);
file2.read((char*)&M1, sizeof(M1));
cout<<"\nInteger data member: "<<M1.d;
cout<<"\nMatrix data member: \n";
for(int i=0;i<10;i++)
{
for(int j=0;j<20;j++)
{
cout<<M1.Mat[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}
This produces the desired output. However, when I separately(using a differnt .cpp file) try to read the above created file using the code below, it doesn't work.
class Matrix{
public:
vector<vector<float>> Mat;
int d;
};
int main()
{
Matrix M1;
ifstream file2("Data_for_Matrix2.bin", ios::in|ios::binary);
if(!file2.is_open()) cout<<"\nFile not open!";
file2.seekg(0);
file2.read((char*)&M1, sizeof(M1));
cout<<"\nInteger data member: "<<M1.d;
cout<<"\nMatrix data member: \n";
for(int i=0;i<10;i++)
{
for(int j=0;j<20;j++)
{
cout<<M1.Mat[i][j]<<" ";
}
cout<<"\n";
}
return 0;
}
The output it generates is,
_Integer data member: 24_
_Matrix data member:_
The process exits without printing the content of the matrix. I unable to identify the issue here. What could be going wrong?
</details>
# 答案1
**得分**: 1
你正在保存`std::vector`的数据成员之一是指向分配存储空间的指针。然后,您读取此指针并尝试对其进行解引用以打印矩阵元素,这是行不通的。矩阵元素甚至没有保存到文件中。
要理解原因,想象一下如果您有`struct Data { float* start; int count; }`,并像您对`Matrix`所做的那样将其存储以备后用。您不会存储元素。您存储指向它们所在位置和它们数量的指针。但它们不会永远存在,即使它们存在,通常另一个进程也无法访问它们(部分原因是出于安全考虑)。
不要像这样序列化`std::vector`。相反,存储大小和元素,然后在读取时创建所需大小的新容器。
或者,如果矩阵的维度始终相同,您可以将`std::vector`替换为`std::array<std::array<float, 20>, 10>`,然后所有矩阵的元素都将存储在`class Matrix`“内部”,您的序列化将正常工作。
<details>
<summary>英文:</summary>
You are saving data members of `std::vector`. One of them is a pointer to the allocated storage. Then you read this pointer and attempt to dereference it to print matrix elements, which can not work. Matrix elements aren't even saved to a file.
To see why, imagine you had `struct Data { float* start; int count; }` and you store it for later like you do with `Matrix`. You don't store the elements. You store a pointer to where they are and their amount. But they won't be there forever, and even while they are, usually another process can't access them (in part due to security considerations).
Don't serialize `std::vector` like this. Store size and elements instead, and create a new container of required size when reading.
Alternatively, if dimensions of the matrix are always the same, you can replace `std::vector` with `std::array<std::array<float, 20>, 10>`, then all elements of a matrix will be stored "inside" `class Matrix` and your serialization will work fine.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论