2008-11-03 8 views
25

J'ai une boucle qui lit chaque ligne dans un fichier en utilisant getline().std :: getline() renvoie

istream is; 
string line; 
while (!getline(is, line).eof()) 
{ 
} 

je remarquai que d'appeler getline() comme cela semble aussi travailler:

while (getline(is, line)) 

Qu'est-ce qui se passe ici? getline() renvoie une référence de flux. Est-ce qu'il est en train d'être converti en un pointeur? Est-ce réellement une bonne pratique ou devrais-je m'en tenir au premier formulaire?

Répondre

26

L'istream retourné par getline() est implicitement appelé par la méthode void *(), qui retourne si le flux a rencontré une erreur. En tant que tel, il fait plus de contrôles qu'un appel à eof().

+0

Charles a raison, vous êtes également déroutant avec l'opérateur fourni par la sentinelle. –

+0

J'ai supprimé mon dernier post pendant que j'écrivais un test. Maintenant, je suis à peu près sûr que ça va faire du bien. –

+0

A moins que votre implémentation de SL ne soit non standard, elle sera annulée *. C'est ce que la norme exige. –

8

Mise à jour: Méthode

j'avais tort signalé à la basic_istream documentation pour le bool de l'opérateur() sur la basic_istream :: classe guérite, mais comme on l'a fait remarquer ce n'est pas réellement ce qui se passe. J'ai voté les bonnes réponses de Charles et Luc. C'est en fait l'opérateur void *() qui est appelé. Plus sur ce in the C++ FAQ.

+0

Vous confondez la sentinelle avec basic_ios :: opérateur void *() -> http://dinkumware.com/ manual/default.aspx? manual = compleat & page = ios.html # basic_ios :: operator% 20void% 20 * –

+0

Bon point. Je suis également corrigé. – tgamblin

+1

votre lien est mort – qdii

-3

Je voudrais coller avec la première forme. Alors que la seconde forme peut fonctionner, elle n'est guère explicite. Votre code original décrit clairement ce qui est fait et comment il devrait se comporter.

+0

Le flux pourrait être mauvais et pas eof(), cependant. Si vous voulez être explicite, vous pouvez appeler good(). – tgamblin

+0

Oui, vous avez raison. Il serait préférable d'utiliser le premier formulaire, mais avec un appel à .good() au lieu de .eof() –

+2

Personnellement, j'aime l'utilisation de cast implicite à bool. Il ressemble à toutes les autres langues qui parcourent les lignes. –

5

Charles a donné le correct answer.

Qu'est-ce que l'on appelle est en effet std::basic_ios::operator void*(), et non sentry::operator bool(), qui est le fait cohérente que std::getline() retourne un std::basic_istream (donc, un std::basic_ios), et non une sentinelle.

Pour les non croyants, voir:

Sinon, comme d'autres l'ont déjà dit, préfèrent la seconde forme qui h est canonique. Utilisez pas fail() si vraiment vous voulez un code verbeux - Je ne me souviens jamais si xxx.good() peut être utilisé au lieu de !xxx.fail()

+0

En effet. dinkumware a supprimé sa documentation en ligne. Lien fixe. Merci. –