Domanda

sostanzialmente, ho il mio tavolo Huffman come

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

Dove stringa è il modello di bit e char è il valore rappresentato da detto modello. Il problema è come posso memorizzarlo come intestazione del mio file compresso in modo da poter ricostruire la stessa mappa quando voglio decodificarlo?

Prova di memorizzarlo come binario:

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

E poi costruendo con:

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

Non funziona, ricevo un errore di inizializzazione della stringa ... qualcosa a che fare con NULL. Eventuali suggerimenti? Se hai un modo migliore di memorizzare bit e valori, mi piacerebbe sentire.

È stato utile?

Soluzione

Puoi farlo da solo o puoi farlo con boost: http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html . Quello che provi attualmente è solo visualizzare la mappa come un semplice tipo di dati vecchio, il che significa essenzialmente che è un tipo di dati C. Ma non lo è, quindi non riesce a salvare / caricare. aumentare la serializzazione lo fa correttamente. Date un'occhiata a questo. Se non vuoi usarlo, puoi fare qualcosa del genere:

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

Si noti che quanto sopra necessita di alcune modifiche se i caratteri memorizzati potrebbero essere anche spazi bianchi. Per questo motivo, è probabilmente il migliore da convertire dapprima in un int prima di scrivere e poi leggere come int durante il caricamento. In realtà, raccomando di aumentare la serializzazione e aumentare iostreams ( http : //www.boost.org/doc/libs/1_37_0/libs/iostreams/doc/index.html ), che include un flusso di compressione in grado di comprimere in modo trasparente anche i tuoi dati.

Altri suggerimenti

Non puoi semplicemente serializzare i valori binari su disco in questo modo. La rappresentazione in memoria non è semplicemente un blocco contiguo di memoria, e anche se lo fosse probabilmente conterrà puntatori relativi all'indirizzo del blocco.

È necessario scorrere l'iter sulla mappa e serializzare ciascun elemento singolarmente. Quindi per riportarli indietro ricostruisci la mappa leggendo gli elementi dal disco uno per uno e reinserendoli nella mappa.

Ottima domanda. Il problema qui è che i contenitori predefiniti non supportano la serializzazione: devi scriverlo tu stesso, è una seccatura, ma è possibile.

Ecco come è possibile serializzare un std::map in un formato testuale. Puoi adattarlo per scrivere in qualsiasi formato binario di cui hai bisogno. Sostituisci l'operatore << con reads e 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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top