2

我想读取这个二进制文件并在屏幕上打印数字,但它正在打印奇怪的字符。我从 MATLAB 生成了这个二进制文件。如何正确显示数据?

#include <iostream>
#include <fstream>
using namespace std;

ifstream::pos_type size;
char * memblock;

int main ()
{
   ifstream file ("seg.bin", ios::in|ios::binary|ios::ate);

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

        cout << "the complete file content is in memory";

        for (int i=0;i<size;i++)
        {
            cout<<memblock[i]<<endl;
        }
    }
    else cout << "Unable to open file";
    return 0;
}
4

3 回答 3

1

您正在将chars 打印到输出,输出中的表示char是一个字符,如果您发送到的字符std::cout不可打印,您将什么也看不到,或者在某些情况下您会看到奇怪的字符(或在某些情况下会发出哔声!)。

尝试将char值转换为int

std::cout << static_cast<int>(memblock[i]) << std::endl;
             ^^^^^^^^^^^^^^^^

您迭代打印数据的方式只会获得 8 位大小(或您的大小char)的数据,假设您的文件中有以下数据:

00000FFF

您的输出将是:

0

0

15

255

但是,如果您正在处理其他大小的数据(int例如),您将期望输出4095(或者如果您04095数据是 16 位宽)。

如果是您的情况,请尝试将数据读入您期望的数据数组中:

const ifstream::pos_type size = file.tellg(); // do not cast the size!
const size_t elements = size / sizeof(int);   // <--- beware of the sizes!
memblock = new int [elements];                // Elements, not size

for (int i = 0; i < elements; ++i) // Elements! not size
{
    std::cout << memblock[i] << std::endl;
}

另一个提示:

  • Declare sizeand elementsas const(你不会在阅读后更改它们):这向你和你的同事表明你打算将此变量视为只读。
  • 不要强制size转换为int,使用返回的类型tellg()或者使用auto……const auto size = file.tellg();为什么要强制转换为另一种类型?使用与您正在调用的函数相同的函数!强制转换可能会导致开销。
  • 尝试在最小的范围内和您将要使用它们的位置附近声明您的变量:这将使您的代码更具可读性和可维护性。
于 2013-07-11T07:44:35.183 回答
0

您需要知道文件中存储的数据类型是什么。假设它是double. 在这种情况下,您可以这样做:

for (int i = 0; i < size; i += sizeof(double))
{
    cout << *(double*)&memblock[i] << endl;
}

另一种方法是直接读入一个数组double。将其留作练习。

于 2013-07-11T05:09:10.430 回答
0

memblock 是 char 类型,这就是 cout 将打印字符(ascii 字符)的原因。在这种情况下,您想要将 memblock 指针重新解释为您需要的类型的指针。假设你需要双倍:

size = (int)file.tellg();
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
double * fileContent = reinterpret_cast<double *>(memblock);
cout << "the complete file content is in memory";

int sizeOfFileContent = sizeof(memblock)/sizeof(double);
for (int i=0; i<sizeOfFileContent; i++)
{
   cout<<fileContent[i]<<endl;
}

只用一个指针回收内存,不要尝试多次删除!

于 2013-07-11T07:50:28.943 回答