2013-03-26 79 views
0

我在这里很新的,我有一个问题 我有一个结构,让我们说整体大小为8个字节,这里的结构:C++解析数据字节到结构

struct Header 
{ 
    int ID;    // 4 bytes 
    char Title [4];  // 4 bytes too 
}; // so it 8 bytes right? 

和我有一个文件8个字节的太... 我只是想问一下,如何解析的文件数据到我已经试过这一个是

的结构:

Header* ParseHeader(char* filename) 
    { 
     char* buffer = new char[8]; 
     fstream fs(filename); 

     if (fs.is_open() != true) 
      throw new exception("Couldn't Open file for Parsing Header."); 

     fs.read(buffer, 8); 

     if (!fs) 
     { 
      delete[] buffer; 
      throw new exception("Couldn't Read header OJN file.\nHeader data was corrupted"); 
     } 

     Header* header = (Header*)((void*)buffer); 
     delete[] buffer; 
     fs.close(); 

     return header; 
    } 

但它失败,并返回我无效的数据比我所期望的(我可以让你确定,这不是文件错误,文件结构正确)

有人可以帮我吗? 感谢

回答

1

好像你做的一切正常,直到这一点:

Header* header = (Header*)((void*)buffer); 
delete[] buffer; 
fs.close(); 

通知您删除缓冲区铸造后,即头球点到已删除的位置 - >垃圾,你需要或者不删除或者如果您仍想使用它,请复制数据。

此外,相当诚实,我不明白你的代码是如何编译,你的功能状态,它返回一个头,当你返回头* ..

+0

谢谢,它帮助我 – SirusDoma 2013-03-26 07:23:18

0

您删除正在被返回的数据。因此header不再可访问。

我觉得你的意思行是:

Header header = *(Header*)((void*)buffer); 

这实际上将复制的标题。

+0

你能解释一下吗? – Kyurem 2013-03-26 07:19:50

0

就C++而言,8字节文件正确映射到struct Header这一事实只是运气。该结构可以具有内部填充,使其大于8个字节,并且数据的字节顺序可能会与您的文件和CPU不同。

我知道你的代码工作您的特定编译器版本,在操作系统你的CPU但你不应该进入编码像的习惯,否则你可能会陷入大只要你改变任何这些参数(或者甚至可能只是一些编译器标志),都会遇到麻烦。换句话说,你在做什么是极坏练习。在C++中,你甚至不能保证int实际上是4个字节。

从文件加载这些二进制数据的正确方法是单独加载每个字段并根据您使用的CPU(例如通过hton*/ntoh*或类似函数)确保正确的字节序转换。使用像int32_t这样的固定尺寸类型也有帮助。

0

只要定义你的结构在1字节边界为:

#pragma pack(1) 
struct Header 
{ 
    int ID;    // 4 bytes 
    char Title [4];  // 4 bytes too 
}; 
#pragma pack() 

首先pack声明指示编译器在结构上使用一个字节填充的成员。这种方式的大小为Header将是8个字节。第二条pack声明指示回到默认设置。您可能需要使用pushpop指令(请参阅enter link description here) - 但这不是您必需的。

其次,更重要的是,您不应该使用像8这样的硬编码值。始终使用sizeof来读取或写入结构。而且,绝对不需要这样的说法:

char* buffer = new char[8]; 
... 

只是声明Header变量本身,并在其上写着:为答案

Header header; 
... 
fs.read(&header, sizeof(Header));