阅读二进制数据问题

时间:2013-10-10 08:46:28

标签: c++ c iostream fstream

我正在尝试以C ++方式读取位图文件。该文件有两个标题(文件标题和图像标题)。我成功地读了他们两个。但是现在我正在尝试读取数据,就像我重写标题一样,我失败了。当我使用C方式读取二进制文件时,一切都很好。这是代码: im_bmp.cpp

#include <iostream>
#include <fstream>
#include "im_bmp.h"

using namespace std;

void read_bmp(const char* f)
{
   pict I; unsigned char pix[3]; px pxl; int i = 0;

   FILE* fl = fopen(f, "rb");
   fread(&I, sizeof(pict), 1, fl);
   printf("%d\n%d\n",I.im.bpp,I.fhd.f_off); // A test to show the bit per pixel and the offset(where image data begin)

   while(i<2)
   {
       fread(&pix,1,3,fl);
       printf("%d %d %d ",pix[2],pix[1],pix[0]); // A test to show the first two pixels
       i++;
   }

// The code below read binary files in the C++ way
/*
   ifstream ifs;
   ifs.open(f,ios::binary);
   ifs.read((char *)&I,sizeof(pict));
   cout << I.im.bpp << endl;           // It works here. It's headers
   ifs.read((char *)&pxl,sizeof(pxl));
   cout << pxl.r << endl;              // It fails here to read the first pixel
*/
   fclose(fl);
}

im_bmp.h

#ifndef IM_BMP_H_INCLUDED
#define IM_BMP_H_INCLUDED

#include <iostream>
#include <fstream>
#pragma pack(1)

using namespace std;
/*
typedef int int32;
typedef short int16;

typedef struct px
{
    unsigned char r, g, b;
} px;

typedef struct pict
{
    int w, h;
    px dt;
} pict;

struct im_hd
{
    int32 hd_sz;
    int32 wdt;
    int32 hgt;
    int16 im_pl;
    int16 bpp;
    int32 cmp;
    int32 im_sz;
    int32 hr;
    int32 vr;
    int32 clr;
    int32 mclr;
};

struct fl_hd
{
    char hd[2];
    int32 sz;
    int32 rsv;
    int32 f_off;
    im_hd im;
};
*/

struct im_hd
{
    int hd_sz;
    int wdt;
    int hgt;
    short im_pl;
    short bpp;
    int cmp;
    int im_sz;
    int hr;
    int vr;
    int clr;
    int mclr;
};

struct fl_hd
{
    char hd[2];
    int sz;
    int rsv;
    int f_off;
    //im_hd im;
};

typedef struct px
{
    unsigned char r, g, b;
} px;

typedef struct pict
{
    fl_hd fhd;
    im_hd im;
    //int w, h;
    //px* dt;
} pict;

void read_bmp(const char* f);

#endif // IM_BMP_H_INCLUDED 

我尝试在C ++中执行此操作,但它不起作用:

   ifstream ifs;
   ifs.open(f,ios::binary);
   ifs.read((char *)&I,sizeof(pict));
   cout << I.im.bpp << endl;           // It works here. It's headers
   ifs.read((char *)&pxl,sizeof(pxl));
   cout << pxl.r << endl;              // It fails here to read the first pixel

1 个答案:

答案 0 :(得分:1)

您的C ++代码完美无缺。它打印出一个奇怪的字符,因为cout将其解释为char

cout << pxl.r << endl; 

尝试将其转换为int以查看整数值:

cout << static_cast<int>(pxl.r) << endl; 

虽然您可能使用#pragma pack强制执行结构对齐,但在不考虑结构大小的情况下读取像素可能更安全:

ifs.read((char *)&pxl.r, sizeof (unsigned char));
ifs.read((char *)&pxl.g, sizeof (unsigned char));
ifs.read((char *)&pxl.b, sizeof (unsigned char));