2013-09-03 4 views
-2

Je suis en train d'écrire un programme pour prendre l'entrée d'un fichier et l'afficher sur la console. Le problème est que la dernière entrée est répétée deux fois. Le code est le suivant: -Valeur répétée à la fin du fichier

int main(void) 
{ 
    string filename; 
    int grades; 
    cout<<"Enter the filename:"<<endl; 
    getline(cin,filename); 
    ifstream inFile(filename.c_str(),ios::in); 
    if(!inFile){ 
     cout<<"File does not exist."<<endl; 
     exit(1); 
    } 
    while(!inFile.eof()) 
    { 
     inFile>>grades; 
     cout<<grades<<endl; 
    } 
    inFile.close(); 
    return 0; 
} 

Pouvez-vous s'il vous plaît m'aider à trouver l'erreur? J'ai cherché sur le web et mon code semble être syntaxiquement et logiquement correct.

+0

des dizaines de messages déjà sur SO, s'il vous plaît faire une petite recherche – P0W

+0

'while (inFile >> grades)' – BoBTFish

+0

Encore une fois: ** Ne pas utiliser 'while (! InFile.eof())'. N'utilisez pas 'while (inFile.good())'. ** Voir [Pourquoi iostream :: eof est-il dans une condition de boucle considérée comme incorrecte?] (Http://stackoverflow.com/questions/5605125/why-is -iostreameof-inside-a-loop-condition-considered-wrong) –

Répondre

2

Ceci est faux

while(!inFile.eof()) 
    { 
     inFile>>grades; 
     cout<<grades<<endl; 
    } 

Ce droit est

while (inFile >> grades) 
{ 
    cout << grades << endl; 
} 

Doit être l'erreur la plus commune sur ce forum. eof() ne vous dit pas que le suivant lu aura une erreur de fin de fichier, il vous indique que la lecture dernière a échoué en raison de la fin du fichier. Donc, si vous devez utiliser eof() vous devez l'utiliser après vous avez lu pas avant.

+0

Il ne vous dit pas si la dernière lecture a échoué. Que 'eof()' retourne vrai ou non après une lecture réussie dépend de ce que vous lisiez, et où vous étiez dans la séquence d'entrée. Tout ce que vous pouvez dire c'est que _if_ 'eof()' renvoie true, la prochaine lecture échouera (mais si elle renvoie false, la prochaine lecture peut échouer aussi). Et que _if_ 'fail()' renvoie true, et 'eof()' est vrai, il y a une bonne chance (mais pas 100%) que la raison de l'échec soit que nous ayons atteint la fin du fichier avant de lire la valeur. –

+0

Et concernant votre dernière phrase: il n'y a aucune utilisation raisonnable de 'eof()' avant que vous ayez détecté un échec par d'autres moyens. Il est seulement utile d'essayer de déterminer la raison d'un échec, c'est-à-dire 'fail() &&! Eof()' signifie que vous avez eu une erreur de format dans l'entrée. –

0

Syntaxiquement correct, oui. Mais pas logiquement. Vous utilisez incorrectement eof().

La première chose à réaliser est que tous les des fonctions dont testent le statut de leurs résultats sur la dernière entrée. Et vous devez toujours vérifier que l'entrée a réussi avant d'utiliser quoi que ce soit que vous avez entré; lorsque vous écrivez:

inFile >> grades; 
std::cout << grades; 

vous n'êtes pas vérifier que l'entrée a réussi avant classes accès. Dans ce cas, si l'entrée échoue, vous obtenez la valeur précédente ; s'il n'y avait pas de valeur précédente, vous obtenez un comportement non défini. Quelque part entre le >> et le <<, vous devez vérifier que le >> a réussi.

La méthode habituelle de vérification du succès consiste à utiliser le flux lui-même comme un booléen. Et parce que le >> renvoie une référence au courant, la façon idiomatiques d'écrire votre boucle serait:

while (inFile >> grades) { 
    std::cout << grades << std::endl; 
} 

D'un point de vue, il est horrible génie logiciel (modification de l'état dans l'état d'un while) , mais l'idiome est si omniprésent que toute autre question soulève des questions.

Ceci s'arrêtera s'il y a une erreur de saisie pour une raison quelconque. Une fois que vous avez vu l'échec (et alors seulement), vous pouvez demander pourquoi:

if (inFile.bad()) { 
    // Serious hardware failure... 
} else if (!inFile.eof()) { 
    // Format error in the input... 
} else { 
    // Normally, no more data in the input stream, but 
    // there are a few special cases where you could still 
    // have a format error and end up here. Not with 
    // `int`, however. 
} 

Mais encore une fois, cela est seulement valide après une entrée a échoué.

Questions connexes