2010-11-02 3 views
0

pour mon affectation Je construis un tas, les données pour le tas proviennent d'un fichier. L'une des fonctions est d'obtenir les données, mais je ne parviens pas à comprendre la fonction de lecture ifstream() et je reçois tout à fait une erreur désagréable à cause de cela ce que j'ai:C++ tas et ifstream fonction de lecture

template<class T, class P> 
void get_list(vector<T>& v, const char* file_loc, P func) { 
    T data; 
    ifstream inFile; 

    inFile.open("file_loc"); 
    if (!inFile) { 
     cerr << "Error - unable to open input file\n"; 
     exit(1); 
    } 

    inFile.read(&data, sizeof(T)); 

    while (inFile) { 
     inFile.read(&data, sizeof(T)); 
     insert(v,data,func); 
    } 

    inFile.close(); 
} 

l'erreur que je reçois est:

prog7.h:53: error: no matching function for call to 
‘std::basic_ifstream<char, std::char_traits<char> >::read(int*, long unsigned int)’ 
/usr/include/c++/4.3/istream:468: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,_Traits>::read(_CharT*, std::streamsize) 
[with _CharT = char, _Traits = std::char_traits<char>] 

toute aide serait très appréciée!

Répondre

2

Le prototype de std :: ifstream :: read est

istream& read (char* s, streamsize n); 

Alors, où vous avez

inFile.read(&data, sizeof(T)); 

devrait être

inFile.read((char*) &data, sizeof(T)); 

Cependant t Il suppose que vous lisez octets bruts à partir d'un fichier binaire. Si vous analysez un fichier texte avec les entiers représentés en caractères ascii décimaux vous pouvez simplement utiliser

inFile >> data; 
+0

'inFile >> data' et' infile.read (...) 'font des choses assez différentes. –

+0

@Marcelo Cantos: En effet. Je pensais juste qu'il devrait être au courant de laquelle de ces deux choses différentes il veut faire. – Akusete

+0

Je viens juste de remarquer l'explication de binary-vs-text dans votre réponse. Vous avez mes excuses si j'étais déjà là quand j'ai écrit mon commentaire. –

4

istream::read prend un char*. Vous aurez besoin de lancer: (char*)&data.

De plus, il y a un bug dans votre code. La lecture peut échouer même après le test du flux. La solution idiomatique est la suivante:

while (inFile.read(&data, sizeof(T))) { 
    insert(v,data,func); 
} 

Dans l'ensemble, votre code pourrait être simplifié; vous pouvez ouvrir le fichier dans le constructeur et laisser le destructeur le fermer. Aussi, je m'interroge sur la première lecture en dehors de la boucle; faites-vous cela avec l'intention d'ignorer la première entrée dans le fichier?

template<class T, class P> 
void get_list(vector<T>& v, const char* file_loc, P func) { 
    T data; 
    ifstream inFile("file_loc"); 
    if (!inFile) { 
     cerr << "Error - unable to open input file\n"; 
     exit(1); 
    } 

    inFile.read(&data, sizeof(T)); 

    while (inFile.read(&data, sizeof(T))) { 
     insert(v,data,func); 
    } 
} 
+0

Si vous préférez le cast C++ ('reinterpret_cast') en C casting? –

+0

@Diego: Le puriste en moi dit oui, mais le pragmatiste en moi n'a jamais vu aucun avantage à rendre un tel code plus verbeux. Au cours des 15 dernières années, j'ai eu une seule occasion où j'ai passé environ cinq minutes à chasser une distribution suspecte qui aurait pris quelques secondes pour trouver si elle avait été écrite comme une réinterprétation.Donc, pour moi, le coût à vie de ne pas utiliser de moules de style nouveau a été d'environ cinq minutes. Correction: il a maintenant doublé à dix minutes parce que je viens de passer environ cinq minutes à réfléchir et à répondre à votre commentaire. –

+0

Haha, je vois. Quoi qu'il en soit, ce n'est pas vraiment une question de temps perdu dans ceci ou cela, mais peut-être en utilisant ce qui est prévu pour l'affaire. –

0

Vous instancié le modèle avec le type int, mais il n'y a pas de fonction surcharge pour la lecture qui prend un pointeur sur un int comme c'est le premier paramètre. Vous pouvez explicitement convertir en char * en utilisant reinterpret_cast.

0

read() attend un char* (c'est-à-dire le type d'élément du flux sous-jacent). Vous avez donc besoin de jeter le pointeur de données char*:

inFile.read(reinterpret_cast<char*>(&data), sizeof(T)); 
0

Vous devez convertir le pointeur vers un char* qui est ce que la lecture attend. Vous devez utiliser reinterpret_cast<char*>(&data) dans le read. Notez que ceci est toujours dangereux, car cette conversion n'est pas vérifiée du tout, et vous devez être vraiment sûr que ce que vous lisez est conforme au type T. Le code n'est pas portable parmi les architectures, les tailles de mots, etc.