如何将二维矢量写入二进制文件
How to write a 2D vector into a binary file?
大家好!我有一个用无符号字符填充的2D矢量。现在我想把它的内容保存到一个二进制文件中:
std::vector<std::vector<unsigned char> > v2D(1920, std::vector<unsigned char>(1080));
// Populate the 2D vector here
.....
FILE* fpOut;
// Open for write
if ( (err = fopen_s( &fpOut, "e:\test.dat", "wb")) !=0 )
{
return;
}
// Write the composite file
size_t nCount = 1920 * 1080 * sizeof(unsigned char);
int nWritten = fwrite((char *)&v2D[0][0], sizeof(unsigned char), nCount, fpOut);
// Close file
fclose(fpOut);
但是,当我阅读test.dat时,填充一个新的2D向量,并将其条目与旧条目进行比较。我发现书面内容与原件不一样。为什么?我的书面陈述怎么了?你能告诉我如何以正确的方式将2D矢量写入二进制文件吗?非常感谢!
#define LON_DATA_ROWS 1920
#define LON_DATA_COLS 1080
std::vector<std::vector<float> > m_fLon2DArray(LON_DATA_ROWS, std::vector<float>(LON_DATA_COLS));
std::ifstream InputFile;
int nSizeOfLonData = TOTAL_LON_ELEMENTS * sizeof(float);
std::vector<char> vLonDataBuffer(nSizeOfLonData);
// Open the file
InputFile.open(m_sNorminalLonLatFile.c_str(), ios::binary);
// Unable to open file pszDataFile for reading
if ( InputFile.fail() )
return false;
// Read longitude data buffer
InputFile.read(&vLonDataBuffer[0], nSizeOfLonData);
// Close the file object
InputFile.close();
// Populate the longitude 2D vector
for (unsigned i = 0; i < LON_DATA_ROWS; i++)
{
memcpy(&m_fLon2DArray[i][0], &vLonDataBuffer[(i * LON_DATA_COLS) * sizeof(float)], LON_DATA_COLS * sizeof(float));
}
// Some operation put here
// Write the results to a binary file
v2D
所包含的数据不在连续存储器中。然而,v2D
(它是一个向量(的每个元素都在连续存储器中。也就是说,v2D[i]
所包含的数据在连续存储器中。
所以你应该这样做:
int nWritten = 0;
for(size_t i = 0; i < v2D.size(); i++ )
{
if ( v2D[i].size() > 0 )
nWritten += fwrite(&v2D[i][0], sizeof(unsigned char), v2D[i].size(), fpOut);
}
或者您可以使用C++IOStream作为:
std::ofstream file("E:\test.data", std::ofstream::binary);
for(size_t i = 0; i < v2D.size(); i++ )
{
if ( v2D[i].size() > 0 )
{
const char* buffer = static_cast<const char*>(&v2D[i][0]);
file.write(buffer, v2D[i].size());
}
}
内存中的矢量看起来不像这样:
|---------|---------|---------|---------|... (where "-" is one element)
0 1 2 3
但更像这样:
|->0x48267a70|->0x894753b2|->0xb8cc92f0|->0x22d8cc71|...
(每个向量都有一个指向其内部数据的指针,当增长超过已经分配的内存量时,这些数据将被重新分配(。
您所做的是获取第一个向量的内部缓冲区的地址,并在耗尽其元素后对其进行过度索引。这是未定义的行为,这就是为什么你的文件中有内存垃圾(但你有同样的机会破坏程序(。
您可以通过迭代将存储的矢量一个接一个地写入文件。在更惯用的C++风格中:
std::ofstream outfile("e:\test.dat", std::ios::binary | std::ios::out);
if (!outfile.is_open()) ... // handle error
for (std::vector<std::vector<unsigned char> >::iterator it = v2D.begin();
it != v2D.end();
++it)
{
outfile.write(&it->front(), it->size() * sizeof(unsigned char));
}
或者,在C++11中,上面的内容看起来是这样的:
for (auto& it : v2D)
{
outfile.write(&it.front(), it.size() * sizeof(unsigned char));
}
在这两种情况下,都应该处理ios_base::failure
异常。
制作2d矩阵有两种主要方法:通过定义n*m个存储器区域或者通过具有指向m个矢量的n个指针的列表。你有后者的变体。
您正在做的是将矢量数据列表写入文件。。。您的数据是不连续的,因此您正在将"vector"类实例数据写入文件中。
您可以一个接一个地写入每个子向量,或者使用1920*1080单个向量,并像以前一样写入文件。
相关文章:
- 将值从二维数组输出到文本文件
- 如何将文本文件读取到二维数组中并以 c++ 打印
- 如何将 numpy 二维数组作为一种可以用C++读取的二进制格式存储在磁盘上
- 如何在C++中将.csv文件的元素存储到二维向量中?
- C++ 如何从文本文件中扫描二维数组并对行求和?
- 有效地从文本文件中读取带有字符串索引的大型二维数组(矩阵)
- 如何将字符从文件放入二维矢量中
- C++ 将二维数据库保存到文件ISSUE中
- 读取.txt文件并组织成二维数组
- 如何在头文件中的类中声明二维数组
- 从二维整数数组中的文件中读取
- 从文件中读取的二维数组作为参数
- 从文本文件读取到表示一个月的二维数组中
- 如何将.txt文件中的浮点数据写入带有VS2017的二维数组
- 我可以在不知道文本文件的列数的情况下读取二维数组中的文件吗?
- 我们如何将电路板从 TXT 文件加载到二维数组中(没有行大小和列大小)
- 二进制 I/O 到具有二维动态数组的文件
- C++到C#将二进制文件读取到二维浮点数组中
- 如何将二维矢量写入二进制文件
- 写/读二维数组二进制文件c++