C++ 从二进制文件读取双类型数据

C++ 从二进制文件读取双类型数据,c++,binary,double,C++,Binary,Double,我想从一个二进制文件中读取双值,并将它们存储在一个向量中。我的值有以下形式:73.6634、73.3295、72.6764等等。我有一段代码,可以在内存中读取和存储数据。由于read函数具有char类型(istream&read(char*s,streamsize n))作为输入,因此它可以完美地与char类型配合使用。当我尝试将char类型转换为double时,我得到的明显的整数值是74、73、73等等。是否有任何函数允许我直接读取双精度值或其他方法 如果我将char*memblock更改为d

我想从一个
二进制文件中读取
值,并将它们存储在一个向量中。我的值有以下形式:73.6634、73.3295、72.6764等等。我有一段代码,可以在内存中读取和存储数据。由于
read
函数具有
char
类型(
istream&read(char*s,streamsize n)
)作为输入,因此它可以完美地与
char
类型配合使用。当我尝试将
char
类型转换为
double
时,我得到的明显的整数值是74、73、73等等。是否有任何函数允许我直接读取双精度值或其他方法

如果我将
char*memblock
更改为
double*memblock
并将
memblock=new char[]
更改为
memblock=new double[]
,编译时会出错,因为同样
read
函数只能有
char
类型输入变量

谢谢,我将感谢您的帮助:)

//读取整个二进制文件
#包括
#包括
使用名称空间std;
int main(){
streampos大小;
char*memblock;
int i=0;
ifstream文件(“example.bin”,ios::in | ios::binary | ios::ate);
if(file.is_open())
{
size=file.tellg();
cout(很抱歉听到“Like I'm 5”的语气,我不知道你知道或不知道多少)

介绍二进制数据 你可能知道,你的电脑不像你那样思考数字

首先,计算机会考虑“基数2”系统中的所有数字。但它不会就此停止。您的计算机还会将一个固定的大小与所有数字关联。它会创建一个固定的数字“宽度”。这个大小(几乎总是)以字节或4位数字为单位。这相当于(非常接近)对数字进行数学运算时的大小[1,1530002]您将所有数字视为

[
 00000001
 00000015
 00030002
]
(双打有点奇怪,但我马上就要开始了)

为了演示的目的,让我们假设上面的每2个字符代表一个字节的数据。这意味着,在计算机中,它考虑如下数字:

[
 00,00,00,01
 00,00,00,15
 00,03,00,02
]
[00,00,00,01,00,00,00,15,00,03,00,02]
文件IO都是按照“字节”(char)大小进行的:它通常不知道读取的是什么。这取决于您自己。当将二进制数据写入文件(至少从数组写入)时,我们只是将其全部转储。因此,在上面的示例中,如果我们将其全部写入文件,如下所示:

[
 00,00,00,01
 00,00,00,15
 00,03,00,02
]
[00,00,00,01,00,00,00,15,00,03,00,02]
但是你必须重新解释它,回到4字节的类型

幸运的是,这在c++中非常容易做到:

size = file.tellg();

cout << "size=" << size << "\n"; 

memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();

cout << "the entire file content is in memory \n";
double* double_values = (double*)memblock;//reinterpret as doubles
for(i=0; i<=10; i++)
{
double value = double_values[i];
cout << "value ("<<i<<")=" << value << "\n";
}
size=file.tellg();
问题是——不能保证由另一个程序(你说的Matlab)编写的二进制数据可以被另一个程序仅仅通过强制转换读回,除非你知道这个辅助程序编写的数据与你的程序编写的数据相同

仅强制转换可能不够——您需要知道写入的数据的确切形式。您需要知道二进制格式(例如IEEE)、每个值占用的字节数、endianess等,以便正确解释数据


你应该做的是——写一个小程序,把你声称这个文件的数字写到另一个文件中。然后看看你刚才在十六进制编辑器中写的文件。然后拿你正在试图读取的文件,它是由MatLab创建的,并将内容与你刚才写的内容并排比较。你看到模式了吗?如果没有,然后要么你必须找到一个,要么忘记它,让两个文件相同。

我看不到将原始数据存储到文件中的代码。否则我们不知道“example.bin”的真正内容是什么是文本吗?还是某种二进制表示法?我知道你说你有一个二进制文件…但是你能用二进制打开它吗mode@PaulMcKenzie我的原始数据是从使用fwrite()函数的Matlab函数存储到二进制文件中的。因此原始数据的形式是双类型值(73.6634、73.3295、72.6764…)我的example.bin文件以二进制格式存储了这些数据。使用
重新解释\u cast
而不是普通的cast难道不更安全吗?@Steve视情况而定。如果你在做类似的、疯狂的类型和模板制作,那么可能。如果你试图让所有代码都具有相同的风格,那么可能。否则,你所做的只是在代码中添加冗长的内容,imho(我们知道可以将基本类型强制转换为基本类型,那么为什么要让编译器这样做呢)但我生活在C和一英尺的C++中,所以我有偏见。@ USE2252592扩展史提夫的评论,这里是一些关于重新解释演员的技术细节:@史提夫。谢谢你的评论和答案。我尝试你所提出的代码>双*双值=(双*)。memblock;
double*double\u values=reinterpret\u cast(memblock);
但是这次我得到的是同一个数字(3.52954e+030),当然是double类型,但与原始数据无关…@user2252592你能1.发布matlab脚本,2.发布文件中的前8个字节吗(你可以得到一个十六进制编辑器,比如HxD)。我已经按照你所说的方式编写和读取了二进制数据,没有任何意外。这可能是一个endianess问题(但没有看到数据,我们无法确定)。我将编辑我的endianess答案。