二进制文件:使用 C++ 编写,使用 MATLAB 读取

Binary files: write with C++, read with MATLAB

提问人:thecharlesman 提问时间:7/26/2022 最后编辑:marc_sthecharlesman 更新时间:9/20/2022 访问量:183

问:

我可以在这方面得到你的支持。这是我的问题:

我在 C++ 代码中有一个浮点数(在数据对象中)的 2D 缓冲区,我使用以下命令将其写入二进制文件中:

ptrToFile.write(reinterpret_cast<char *>(&data->array[0][0]), nbOfEltsInArray * sizeof(float));

数据包含 8192 个浮点数,我(正确地?)从这行代码中得到一个 32 KB(8192 * 4 字节)的文件。

现在我想使用 MATLAB 读取该二进制文件。代码为:

hdr_binaryfile = fopen(str_binaryfile_path,'r');
res2_raw = fread(hdr_binaryfile, 'float');
res2 = reshape(res2_raw, int_sizel, int_sizec);

但它并没有像我预期的那样发生。如果我使用 std::cout 在 C++ 代码中打印数据数组,我得到:

pCarte_bin->m_size = 8192
pCarte_bin->m_sizel = 64
pCarte_bin->m_sizec = 128
pCarte_bin->m_p[0][0] = 1014.97
pCarte_bin->m_p[0][1] = 566946
pCarte_bin->m_p[0][2] = 423177
pCarte_bin->m_p[0][3] = 497375
pCarte_bin->m_p[0][4] = 624860
pCarte_bin->m_p[0][5] = 478834
pCarte_bin->m_p[1][0] = 2652.25
pCarte_bin->m_p[2][0] = 642077
pCarte_bin->m_p[3][0] = 5.33649e+006
pCarte_bin->m_p[4][0] = 3.80922e+006
pCarte_bin->m_p[5][0] = 568725

在MATLAB方面,在我使用上面的小代码块读取文件后:

size(res2) = 64  128
res2(1,1) = 1014.9659
res2(1,2) = 323288.4063
res2(1,3) = 2652.2515
res2(1,4) = 457593.375
res2(1,5) = 642076.6875
res2(1,6) = 581674.625
res2(2,1) = 566946.1875
res2(3,1) = 423177.1563
res2(4,1) = 497374.6563
res2(5,1) = 624860.0625
res2(6,1) = 478833.7188

大小(行、列)以及第一项(C++ 中的 [0][0] == MATLAB 中的 [1][1])都可以。但:

  1. 我正在阅读列中的C++行元素:C++中的[0][1],MATLAB中的==[1][2](请记住,MATLAB中的索引从1开始)等。
  2. 我正在从另一个维度的两个元素中读取一个正确的元素:C++中的[1][0],MATLAB中的[1][3],[2][0]==[1][5]等。

对此有什么想法吗?

谢谢! 再见

C++ 数组 MATLAB IO

评论

1赞 MikeCAT 7/26/2022
如何定义?请发布一个最小的、可重复的示例data->array
1赞 PaulMcKenzie 7/26/2022
我有一个浮点数的 2D 缓冲区——如果数据不包含为连续数组,则该代码将不起作用。这就是为什么需要一个最小的可重现的例子来说明如何创建该缓冲区。
1赞 wohlstad 7/26/2022
不确定它是否相关,但 matlab 内存布局是列优先的,而在 C++ 中它通常是行优先的。难道你的矩阵被转置了?
1赞 john 7/27/2022
不确定 matlab,但在 C 或 C++ 中,正确的代码是 .在读取或写入二进制数据时,额外的内容很重要。fopen(str_binaryfile_path,'rb');b

答:

2赞 user18462886 7/26/2022 #1

撇开似乎存在一些精度差异(可能是 MATLAB 中的显示设置)这一事实不谈,这里的问题可能是数据的行主要顺序和列主要顺序之间的差异。如果没有更多细节,将很难确定。特别是,MATLAB 是列,这意味着磁盘上的连续内存被解释为在一列而不是一行中详细说明顺序元素。

可能的解决方案是反转重塑中的两个大小,并访问索引反转的元素。也就是说,交换int_size1和int_size2,然后读取期望的元素

pCarte_bin->m_p[0][0] = res2(1,1)
pCarte_bin->m_p[0][1] = res2(2,1)
pCarte_bin->m_p[0][2] = res2(3,1)
pCarte_bin->m_p[0][3] = res2(4,1)
pCarte_bin->m_p[1][0] = res2(1,2)

等。

您也可以在读取后在 MATLAB 中转置数组,但对于大型数组,这本身可能很昂贵