C ++霍夫曼代码头

时间:2008-12-09 01:27:06

标签: c++ tree header binaryfiles

基本上,我把我的霍夫曼表作为

std::map<std::string, char> ciMap;

其中string是位模式,char是由所述模式表示的值。 问题是如何将其存储为我的压缩文件的标题,以便在我想要解码时再次构建相同的地图?

尝试将其存储为二进制文件:

size_t mapLen = ciMap.size();
outFile.write(reinterpret_cast<char*>(&mapLen), sizeof(size_t));
outFile.write(reinterpret_cast<char*>(&ciMap), sizeof(ciMap));

后来建设:

inFile.read(reinterpret_cast<char*>(&mapLen), sizeof(size_t));
inFile.read(reinterpret_cast<char*>(&ciMap), sizeof(mapLen));

不起作用,我收到字符串初始化错误...与NULL有关。有什么建议?如果你有更好的方法来存储我想听到的位和值。

3 个答案:

答案 0 :(得分:4)

你可以自己做,或者你可以通过提升:http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html来做。您目前尝试的只是将地图视为普通的旧数据类型,这实质上意味着它是一种C数据类型。但事实并非如此,因此无法保存/加载。 boost序列化正确完成。看看它。如果你不想使用它,你可以这样做:

typedef std::map<std::string, char> my_map;
my_map ciMap;

// saving
std::ofstream stream("file.txt");
for(my_map::const_iterator it = ciMap.begin(); it != ciMap.end(); ++it) {
    stream << it->first << " " << it->second << std::endl;
}

// loading
char c;
std::string bits;
std::ifstream stream("file.txt");
while(stream >> bits >> c)
    ciMap.insert(std::make_pair(bits, c));

请注意,如果存储的字符也可能是空白字符,则上述操作需要进行一些更改。因此,在写出之前首先转换为int,然后在加载时作为int读取可能是最好的。实际上,我建议使用boost序列化,并增强iostreams(http://www.boost.org/doc/libs/1_37_0/libs/iostreams/doc/index.html),其中包括一个透明地压缩数据的压缩流。

答案 1 :(得分:3)

您不能以这种方式将二进制值序列化到磁盘。内存表示不仅仅是一个连续的内存块,即使它可能包含相对于块地址的指针。

您需要遍历地图并逐个序列化每个项目。然后将它们带回来,通过逐个读取磁盘上的项目并将它们重新插入地图来重建地图。

答案 2 :(得分:2)

好问题。这里的问题是默认容器不支持序列化 - 你必须自己编写,这很痛苦,但它是可能的。

以下是将std::map序列化为文本格式的方法。您可以调整它以写入您需要的任何二进制格式。只需将<<运算符替换为readswrites

template<typename K, typename V>
std::ostream &operator << (std::ostream &out, const std::map<K,V> &map) {
    out << "map " << map.size() << "\n";
    for (typename std::map<K,V>::const_iterator i = map.begin(); i != map.end(); ++i) {
        out << (*i).first << "\n" << (*i).second << "\n";
    }
    return out;
}

template<typename K, typename V>
std::istream &operator >> (std::istream &in, std::map<K,V> &map) {
    std::string mapkeyword;
    size_t num;
    in >> mapkeyword >> num;
    for (size_t i = 0; i < num; ++i) {
        K key; V value;
        in >> key >> value;
        map[key] = value;
    }
    return in;
}