2009-10-08 6 views
0

J'essaie de lire dans une liste de mots et de les enregistrer dans une hash_map C++ STL avec leur position dans le fichier trié par ordre alphabétique. L'idée est plus tard je vais devoir être capable de dire si une chaîne est un mot et si elle vient avant ou après un mot différent.C++ Lire le fichier dans hash_map

ifstream f_dict ("dictionary.txt"); 
__gnu_cxx::hash_map <const char*, int> dictionary; 
string temp_str; 
int counter = 0; 
while (!f_dict.eof()) { 
    f_dict >> temp_str; 
    dictionary.insert(make_pair(temp_str.c_str(), counter++)); 
} 

Le problème que je rencontre est qu'il ne sauvegarde pas le mot actuel. Le for loop ci-dessous imprime une sélection de mots, mais iter->first est toujours vide. Qu'est-ce que je rate?

__gnu_cxx::hash_map<const char*, int>::iterator iter; 
int i = 0; 
for (iter = dictionary.begin(); iter != dictionary.end() && i < 150; iter++) { 
    cout << "word: " << iter->first << " index: " << iter->second << "\n"; 
    i++; 
} 

Répondre

3

Vous essayez de stocker le même const char * pour chaque mot, car vous ne créez jamais de nouvelle mémoire pour le mot extrait du fichier. Si vous imprimez le pointeur renvoyé par temp_str.c_str(), il en sera de même pour tous les appels de votre première boucle. Dans votre deuxième boucle, vous imprimez le même caractère * pour chaque enregistrement de votre carte (notez qu'il n'y a qu'une seule carte b/c qui n'autorise pas les dups) qui a été définie pour que la chaîne soit vide dans la 1ère boucle ou entre votre boucle pour.

Voici un exemple de code qui illustre le problème et une solution.

#include <fstream> 
#include <iostream> 
#include <map> 

using namespace std; 

int main (int argc, char **argv) 
{ 
    ifstream file("test.txt"); 
    map<const char *, int> dictionary; 
    map<string, int>  strDictionary; 

    string temp_str; 
    int counter = 0; 
    while (!file.eof()) 
    { 
     file >> temp_str; 
     cout << "PARSED: " << temp_str << "\n"; 
     cout << "INSERTING: " << (unsigned long) temp_str.c_str() << "\n"; 
     dictionary.insert(make_pair(temp_str.c_str(), counter)); 
     strDictionary.insert(make_pair(temp_str, counter)); 
     counter++; 
    } 

    cout << "Dictionary Size: " << dictionary.size() << "\n"; 
    cout << "Str Dictionary Size: " << strDictionary.size() << "\n"; 

    for (map<const char*, int>::const_iterator iter = dictionary.begin(); 
     iter != dictionary.end(); 
     ++iter) 
    { 
     cout << "CHAR * DICTINARY: " << iter->first << " -> " << iter->second << "\n"; 
    } 

    for (map<string, int>::const_iterator iter = strDictionary.begin(); 
     iter != strDictionary.end(); 
     ++iter) 
    { 
     cout << "STR DICTIONARY: " << iter->first << " -> " << iter->second << "\n"; 
    } 
    return 1; 
} 
0

Vous voulez utiliser std :: string comme type clé, non const char *, sinon la chaîne ne sera pas copié, et vous vous retrouverez avec la même clé sur chaque insert.