2010-08-31 16 views
1

Je construis initialement un mécanisme de type index, lis chaque ligne du fichier texte en utilisant getline, vérifie si elle correspond à une déclaration d'en-tête connue (string.compare) et enregistre la position tellg en tant que index à ce point. Mon intention est alors d'utiliser seekg (index, ios :: beg) pour chercher l'endroit dans le fichier où se trouve l'en-tête. Après avoir lu le fichier une fois lors de la construction de mon index et en appelant seekg (0, ios :: beg), le prochain getline retourne une chaîne vide où je m'attends à voir la première ligne dans le fichier.Utilisation de getline lors de la lecture à partir d'un fichier texte

une partie de mon code est ci-dessous pour mieux mettre en évidence mon problème

//build the index 
while (! m_fileIn.eof()) 
{ 
    getline (m_fileIn,lineRead); 
    int lineID = getLineID(lineRead); 
    if(lineID==1)  //if its an STRM 
    { 
    //save the index 
    } 
} 

// start reading the file data 
m_fileIn.seekg(0,ios::beg); 
//read first line (title) 

la fonction getLineID retourne un int en fonction du résultat de la comparaison de chaînes.

est l'utilisation de getline incorrecte si j'ai besoin de relire le fichier?

+0

Comment lisez-vous vos informations à partir du fichier après avoir généré votre index? –

+0

J'utilise à nouveau la fonction getline – Dougie

Répondre

2

Votre problème est dû au fait que vous avez défini un mauvais bit dans le flux.
Les opérations sur le flux seront ignorées jusqu'à ce que le bit incorrect ait été réinitialisé.

// After the loop reset the Bad Bits. 
m_fileIn.clear() 

Note: Un mauvais bit est l'une des nombreuses conditions d'erreur, y compris EOF

Mais ce n'est pas vos problèmes majeurs:

Vous utilisez le Classic anti pattern pour la lecture d'un fichier:
utiliser plutôt ce.

while (getline (m_fileIn,lineRead)) 
{ 
    int lineID = getLineID(lineRead); 
    if(lineID==1)  //if its an STRM 
    { 
    //save the index 
    } 
} 

Le problème est que l'EOF n'est pas défini tant que vous ne l'avez pas lu.
La dernière lecture valide indique UPTO mais pas EOF (donc EOF n'est pas défini). Par conséquent, considérez la situation où vous avez lu la dernière ligne du fichier. L'EOF n'a pas été défini car vous ne l'avez pas lu. Donc la boucle est entrée. Vous exécutez maintenant getline(). Cela essaie de lire après EOF car il n'y a absolument aucune donnée à lire (pas un seul octet). Donc getline() échoue maintenant vous appelez getlineID() en utilisant lineRead dont la valeur est indéterminée (la norme ne dit pas ce qui arrive à lineRead quand la condition EOF est atteinte, mais elle a probablement la valeur de dernière ligne lue car vous ne semblez pas pour le réinitialiser dans la boucle).

Un autre problème avec ce code est qu'il vérifie uniquement EOF. Que se passe-t-il lorsqu'un autre type d'erreur se produit? La boucle est bloquée dans une boucle infinie; En effet, lorsqu'un indicateur d'erreur est défini, il n'y a plus de lecture, donc vous ne pouvez jamais atteindre l'EOF.

while (! m_fileIn.eof()) 
{ 
    getline (m_fileIn,lineRead) 
    int lineID = getLineID(lineRead); 
    if(lineID==1)  //if its an STRM 
    { 
    //save the index 
    } 
} 

La solution consiste à effectuer l'opération de lecture dans le test de boucle while. Cela fonctionne parce que getline() renvoie le flux passé comme premier paramètre. Par conséquent, le flux est utilisé dans un contexte booléen. Lorsqu'un flux est utilisé dans un contexte booléen, il est converti en un type pouvant être utilisé comme un booléen. la valeur de cet objet est équivalente à true s'il n'y a pas d'erreur et false sinon.

Dans cette situation, la lecture est tentée, mais en cas d'échec, la boucle n'est jamais entrée.

1

Après avoir affiché ici et la pêche au chalut différents sites j'ai ajouté la ligne

m_fileIn.clear(); 

avant la ligne

getline (m_fileIn,lineRead); 

en effaçant les drapeaux d'erreur (je suppose erreur EOF) J'ai pu continuer comme d'habitude.

Martin - Je serais vraiment intéressé d'en savoir plus sur l'anti-pattern que j'ai utilisé sans le savoir, j'ai mis à jour mon code pour inclure vos changements, merci beaucoup.

+0

Voici l'anti-pattern: - 'while (! M_fileIn.eof())' Ne l'utilise pas. Cet anti-pattern n'est pas spécifique au C++ mais général à toutes les langues (je sais). De Perl -> Php -> Python -> C -> Java -> Fortran etc etc Les fichiers sont toujours lus de la même manière (faire l'opération de lecture dans le cadre de l'expression conditionnelle de la boucle). –