使用C++读取二进制文件

huangapple go评论53阅读模式
英文:

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(&quot;Data_for_Matrix2.bin&quot;, ios::binary|ios::trunc);
if(!file.is_open()) cout&lt;&lt;&quot;\nfile error!!&quot;;
file.write((char*)&amp;M, sizeof(M));
file.close();

ifstream file2(&quot;Data_for_Matrix2.bin&quot;, ios::binary|ios::ate);
if(!file2.is_open()) cout&lt;&lt;&quot;\nFile not open!&quot;;
file2.seekg(0);
file2.read((char*)&amp;M1, sizeof(M1));
cout&lt;&lt;&quot;\nInteger data member: &quot;&lt;&lt;M1.d;
cout&lt;&lt;&quot;\nMatrix data member: \n&quot;;

for(int i=0;i&lt;10;i++)
{
	for(int j=0;j&lt;20;j++)
	{
		cout&lt;&lt;M1.Mat[i][j]&lt;&lt;&quot;    &quot;;
	}
	cout&lt;&lt;&quot;\n&quot;;
}
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&#39;t work.


class Matrix{
public:
vector<vector<float>> Mat;
int d;
};
int main()
{
Matrix M1;

ifstream file2(&quot;Data_for_Matrix2.bin&quot;, ios::in|ios::binary);
if(!file2.is_open()) cout&lt;&lt;&quot;\nFile not open!&quot;;
file2.seekg(0);

file2.read((char*)&amp;M1, sizeof(M1));
cout&lt;&lt;&quot;\nInteger data member: &quot;&lt;&lt;M1.d;
cout&lt;&lt;&quot;\nMatrix data member: \n&quot;;

for(int i=0;i&lt;10;i++)
{
	for(int j=0;j&lt;20;j++)
	{
		cout&lt;&lt;M1.Mat[i][j]&lt;&lt;&quot;    &quot;;
	}
	cout&lt;&lt;&quot;\n&quot;;
}
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&#39;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&#39;t store the elements. You store a pointer to where they are and their amount. But they won&#39;t be there forever, and even while they are, usually another process can&#39;t access them (in part due to security considerations).

Don&#39;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&lt;std::array&lt;float, 20&gt;, 10&gt;`, then all elements of a matrix will be stored &quot;inside&quot; `class Matrix` and your serialization will work fine.

</details>



huangapple
  • 本文由 发表于 2023年6月26日 20:57:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76556918.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定