Вопрос

по сути, у меня есть таблица Хаффмана как

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

Где строка — это битовый шаблон, а 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.Какие-либо предложения?Если у вас есть лучший способ хранения битов и значений, я хотел бы услышать.

Это было полезно?

Решение

Вы можете сделать это самостоятельно, а можете сделать это с помощью boost: 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 при загрузке.На самом деле, я рекомендую повысить сериализацию и повысить iostreams (http://www.boost.org/doc/libs/1_37_0/libs/iostreams/doc/index.html), который включает поток сжатия, который также может прозрачно сжимать ваши данные.

Другие советы

Таким способом вы не можете просто сериализовать двоичные значения на диск.Представление в памяти — это не просто непрерывный блок памяти, и даже если бы оно было таковым, оно, скорее всего, будет содержать указатели, относящиеся к адресу блока.

Вам нужно перебрать карту и сериализовать каждый элемент индивидуально.Затем, чтобы вернуть их обратно, вы реконструируете карту, считывая элементы с диска один за другим и повторно вставляя их на карту.

Отличный вопрос.Проблема здесь в том, что контейнеры по умолчанию не поддерживают сериализацию — вам придется написать ее самостоятельно, это неприятно, но возможно.

Вот как вы можете сериализовать std::map в текстовый формат.Вы можете адаптировать его для записи в любой необходимый вам двоичный формат.Просто замените << оператор с reads и writes.

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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top