2010-04-24 44 views
0

我想使用fread()从文件读取加密的结构数据。一旦我得到解密的结构字节,我想把它放回到这个结构中。结构到字节

struct data 
{ 
    std::string s1; 
    std::string s2; 
    std::string s3; 
    LONG l; 
}; 

你会如何将一个结构转换为可以从字节重建的字节?

+2

是串的std :: string?如果不是,那是什么? – 2010-04-24 23:17:24

+0

戴夫, 这是混乱。你是说结构中的标识符'string'实际上是一个char *的typedef?这就是尼尔所要求的。 – zumalifeguard 2010-04-24 23:41:35

+0

一个问题是LONG数据类型没有很好的定义......在一台计算机上它可能是32位,在另一台计算机上它可能是64位。除非数据永远不会出现在单个计算机之外,否则最好使用int32_t或其他具有明确定义的位宽的类型。 – 2010-04-25 02:31:40

回答

1

问题是std::string不包含有问题的字节,它包含一个指针到您实际想要存储的字节。您应该将每个字符串保存为一个以null结尾的字符串,然后在该文件中保存一个很长的原始文件。

如果您正在寻找像.NET提供的“点击式”序列化解决方案,那么在C++中找不到您想要的内容。 Boost's serialization library可能会有所帮助,因为它会为您序列化一些标准库对象,但您需要自己实现用于用户定义的类。

0

对于一般情况,编写一个函数来手动序列化结构中的所有成员,另一个函数通过依次反序列化所有成员来从字节流创建一个结构。你可以使用脚本来为你生成这些函数(不幸的是,C++不支持像Java反射这样的东西)。

你可以看看boost/serialization

+0

说服为什么这需要一个downvote! – Joshua 2010-04-25 01:15:59

+0

只有一个结构,这是打破了一个轮子上的蝴蝶,但我认为它也不应该得到一个downvote太,因为他写了“的一般情况下”。 – 2010-04-25 01:23:36

1

我会做这样的事情:

struct serialized_data { 
    size_t s1_offset; 
    size_t s2_offset; 
    size_t s3_offset; 
    long l; 
    char strings[1]; 
}; 

serialized_data* serialize (data d) { 
    serialized_data* s = malloc(sizeof(serialized_data) + d.s1.length() + d.s2.length() + d.s3.length() + 3); 
    s->s1_offset = 0; 
    s->s2_offset = d.s1.length() + 1; 
    s->s3_offset = s2_offset + d.s2.length() + 1; 
    s->l = d.l; 
    strcpy(s->strings, d.s1.c_str()); 
    strcpy(s->strings + s->s2_offset, d.s2.c_str()); 
    strcpy(s->strings + s->s3_offset, d.s3.c_str()); 

    return s; 
} 
+0

请记住处理有人通过反序列化代码中的垃圾偏移量/长度的情况。 – 2010-04-25 00:03:19

0
struct data 
{ 
    std::string s1; 
    std::string s2; 
    std::string s3; 
    long l; 
}; 


int Write(FILE* file, const data* myData) 
{ 
    unsigned long length; 

    length = myData->s1.size(); 
    fwrite((void*) &length, sizeof(length), 1, file); 
    fwrite((void*) myData->s1.data(), length, 1, file); 
    ... // write the other strings and long here 
} 

int Read(FILE* file, data* myData) 
{ 
    unsigned long length; 
    char* buffer; 

    fread((void*) &length, sizeof(length), 1, file); 
    buffer = new char[length]; 
    length = fread(&buffer, length, 1, file); 
    myData.s1 = string(buffer, length); 
} 

当然,做错误检查,什么不能