2013-10-10 39 views
0

我正在尝试以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 
+0

Hav你检查了'ifs'的内部标志吗? – Geoffroy

+0

你说“它失败了”,但你有什么输出?你在期待什么? – zakinster

回答

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)); 
+2

一个很好的例子说明为什么“它在这里失败”并不是一个充分的问题描述。 – Adam

+0

谢谢Zakinster,那正是我的问题,并且你解决了它。 – Patrik