C++读取二进制文件,其中包含类型为double的数字

C++ Read Binary file containing numbers of type double

本文关键字:类型 double 数字 包含 读取 二进制文件 C++      更新时间:2023-10-16

我有一个二进制文件,其中包含double类型的数字
此处提供示例输入文件:www.bobdanani.net/download/A.0.0
我想看一下这份文件,把里面的数字打印出来。这就是我所做的:

char* buffer;
int length;
string filename = "A.0.0";
ifs.open (filename.c_str(), ios::in | ios::binary);
// get length of file:
ifs.seekg (0, ios::end);
length = ifs.tellg();
ifs.seekg (0, ios::beg);
// allocate memory:
buffer = new char [length];
// read data as a block:
ifs.read (buffer,length);
ifs.close();
cout.write (buffer,length);
cout << buffer << endl;
delete[] buffer;

我也试过在打印数字时使用类型转换来加倍,但我得到了奇怪的字符。最好的方法是什么?我需要这个二进制文件的数据作为并行程序函数的输入。但这超出了这个问题的范围。

虽然我可能错了,因为你说数字用制表符/空格分隔,我愿意这实际上是ASCII数据,而不是原始二进制数据。因此,使用浮点值的最佳方法是在ifstream对象上使用operator>>,然后将其推送到double中。这将自动将输入值转换为双精度,因为您所做的只是复制组成浮点值但本身不是浮点值的字符字节。此外,如果你试图像字符串一样输出缓冲区,你还没有明确地对其进行null终止,所以它会一直读取堆栈,直到遇到null终止符,或者由于访问操作系统不允许你从堆栈顶部访问的内存而导致分段错误。但不管怎样,最终,缓冲区都不会是double数据类型的表示。

所以你会有这样的东西:

double my_double_val;
ifs.open (filename.c_str());
if (ifs)
{
    ifs >> my_double_val;
}
else
{
    cerr << "Error opening file" << endl;
}
ifs.close();
cout << "Double floating point value: " << my_double_val << endl;
cout.write (buffer,length);

不要这样!上面将把二进制数据转储到标准输出。

cout << buffer << endl;

也不要这样做!上面的操作将把二进制数据转储到第一个字节(恰好为零),以进行标准输出。如果没有这样的字节,它将继续经过缓冲区的末尾(因此是未定义的行为)。

如果缓冲区真的包含双打,并且只有双打,那么你可以做一些讨厌的事情,比如

double * dbuf = reinterpret_cast<double*>(buffer);
int dlength = length / sizeof(double);

使用C++中的系统函数调用(假设您使用的是unix操作系统),并将'od -e filename'作为系统函数调用的参数。然后,您可以轻松地通过管道传输它返回的值并读取它们。这是一种方法。当然,还有许多其他方法可以做到这一点。