Pregunta

Básicamente, tengo mi mesa Huffman como

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

Donde string es el patrón de bits y char es el valor representado por dicho patrón.El problema es ¿cómo almaceno eso como encabezado de mi archivo comprimido para poder volver a crear el mismo mapa cuando quiera decodificarlo?

Intentando almacenarlo como binario:

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

Y luego construyendo con:

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

No funciona, aparece un error de inicialización de cadena...algo que ver con NULL.¿Alguna sugerencia?Si tiene una mejor manera de almacenar los bits y valores, me gustaría escucharlos.

¿Fue útil?

Solución

Puede hacerlo usted mismo, o puede hacerlo con boost: http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html . Lo que intenta actualmente es ver el mapa como un tipo de datos simple y antiguo, lo que esencialmente significa que es un tipo de datos C. Pero no lo es, por lo que no puede guardar / cargar. impulsar la serialización lo hace correctamente. Échale un vistazo. Si no desea usarlo, puede hacer algo como esto:

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

Tenga en cuenta que lo anterior necesita algunos cambios si los caracteres almacenados también podrían ser espacios en blanco. Debido a eso, probablemente sea mejor convertir primero a int antes de escribir, y luego leer como int al cargar. En realidad, recomiendo aumentar la serialización y aumentar los iostreams ( http : //www.boost.org/doc/libs/1_37_0/libs/iostreams/doc/index.html ), que incluye una secuencia de compresión que también puede comprimir sus datos de forma transparente.

Otros consejos

No puede simplemente serializar los valores binarios al disco de esta manera. La representación en memoria no es simplemente un bloque contiguo de memoria, e incluso si lo fuera, probablemente contendrá punteros relativos a la dirección del bloque.

Debe iterar sobre el mapa y serializar cada elemento individualmente. Luego, para recuperarlos, reconstruya el mapa leyendo los elementos del disco uno por uno y volviéndolos a insertar en el mapa.

Gran pregunta.El problema aquí es que los contenedores predeterminados no admiten la serialización; debe escribirlo usted mismo, es complicado, pero es posible.

Así es como puedes serializar un std::map a un formato textual.Puedes adaptarlo para escribir en cualquier formato binario que necesites.Simplemente reemplace el << operador con reads y 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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top