我想从double
文件中读取binary
值,并将它们存储在向量中。我的值具有以下形式:73.6634,73.3295,72.6764等。我有这个代码,可以在内存中读取和存储数据。它与char
类型完美配合,因为read
函数的输入为char
类型(istream& read (char* s, streamsize n)
)。当我尝试将char
类型转换为double
时,我显然得到整数值74,73,73等等。是否有任何函数允许我直接读取双值或任何其他方式?
如果我将char * memblock
更改为double * memblock
而将memblock = new char[]
更改为memblock = new double[]
,则在编译时会出现错误,因为read
函数只能char
输入变量...
谢谢,非常感谢您的帮助:)。
// reading an entire binary file
#include <iostream>
#include <fstream>
using namespace std;
int main () {
streampos size;
char * memblock;
int i=0;
ifstream file ("example.bin", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
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";
for(i=0; i<=10; i++)
{
double value = memblock [i];
cout << "value ("<<i<<")=" << value << "\n";
}
};
delete[] memblock;
}
else cout << "Unable to open file";
return 0;
}
答案 0 :(得分:10)
(抱歉“喜欢我5岁”的语气,我不知道你有多少知道或不知道)
您可能知道,您的计算机并不像您那样考虑数字。
首先,计算机会考虑“基础2”系统中的所有数字。但它并不止于此。您的计算机还将固定大小与所有数字相关联。它创建了数字的固定“宽度”。此大小(几乎总是)以字节为单位,或4位数组。这是(非常接近)相当于,当您对数字[1,15,30002]进行数学运算时,您将所有数字视为
[
00000001
00000015
00030002
]
(双打有点奇怪,但我会在一秒钟内完成这一点。)
让我们假装出于演示目的,上面每2个字符代表一个字节的数据。这意味着,在计算机中,它会考虑这样的数字:
[
00,00,00,01
00,00,00,15
00,03,00,02
]
文件IO全部按照“字节”(字符)大小完成:它通常不知道它正在读取什么。您可以自己解决这个问题。将二进制数据写入文件(至少从一个数组中)时,我们只需将其全部转储。所以在上面的例子中,如果我们将它全部写入文件,如下所示:
[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";
}
这基本上就是说,将那些字节(char)解释为double。
Endianness(再次,LI5)计算机写入数字的顺序。您习惯于从左到右(25,25)写入十五个,但从右到左(52,五十二)编写数字同样有效。我们有big-endian(最低地址的最高有效字节)和little-endian(最高地址的MSB)。
这在体系结构或虚拟机之间从未标准化......但如果他们不同意,您可能会得到奇怪的结果。
不完全符合您的问题,但我必须指出双打是一种特殊情况:虽然阅读和写作看起来相同,但基础数据不仅仅是一个简单的数字。我喜欢将双打视为计算机的“科学记法”。双重标准使用底座和电源来获取您的号码。 在与长相同的空间中存储(符号)(a ^ x)。这给出了一个更大的动态范围的值表示,但是你松散了字节的“人类可读性”,并且你获得了相同数值的值,因此你可以放松精度(尽管它的相对精度,就像科学一样符号,所以你可能无法区分十亿和一十亿和二十,但是1和2是TINY与数字相比)。
我们不妨指出一个C ++的怪癖:你必须确保在编写数据时,它不会尝试将文件重新格式化为ascii。 http://www.cplusplus.com/forum/general/21018/
答案 1 :(得分:0)
问题是这个 - 不能保证由另一个程序(你说Matlab)写的二进制数据只能通过转换被另一个程序读回,除非你知道这个辅助程序写的数据是相同的作为您的程序写的数据。
仅仅强制转换可能还不够 - 您需要知道所写数据的确切形式。您需要知道二进制格式(例如IEEE),每个值占用的字节数,字节顺序等,以便您可以正确地解释数据。
你应该做的是 - 编写一个小程序,将你声称这个文件的号码写到另一个文件中。然后查看您在十六进制编辑器中编写的文件。然后获取您尝试阅读的文件,该文件由MatLab创建,并将内容与您刚编写的文件并排比较。你看到一个模式吗?如果没有,那么要么你必须找到一个,要么忘掉它并让两个文件保持一致。