web-dev-qa-db-fra.com

ifstream: vérifier si ouvert avec succès

Un collègue vient de me dire que ce code:

std::ifstream stream(filename.c_str());
if (!stream)
{
    throw std::runtime_error("..");
}

serait faux. Il a dit que ifstream est évalué à 0 si l'ouverture est réussie. Mon code fonctionne, mais je voulais trouver la documentation mais je n'ai pas vu où il était indiqué comment vérifier si l'ouverture avait réussi. Pouvez-vous me l'indiquer?

40
Philipp

operator!est surchargé pour std::ifstream, Donc vous pouvez faire cela.

À mon avis, cependant, il s'agit d'un horrible abus de surcharge des opérateurs (par le comité des normes). Il est beaucoup plus explicite ce que vous vérifiez si vous faites simplement if (stream.fail()).

49

Vous pouvez faire en sorte qu'un flux particulier lève une exception sur n'importe quel élément eof/fail/bad en appelant sa fonction ios :: exceptions () avec le masque de bits approprié. Vous pouvez donc réécrire l'exemple de la question initiale ci-dessus:

std::ifstream stream;
stream.exceptions(std::ios::failbit | std::ios::badbit);
stream.open(filename.c_str());

Ici, le flux lèvera une exception lorsque le failbit ou le badbit sera défini. Par exemple, si ifstream :: open () échoue, il définira le failbit et lèvera une exception. Bien sûr, cela lèvera une exception plus tard si l'un de ces bits est défini sur le flux, donc cette réécriture n'est pas exactement la même que l'exemple initial. Tu peux appeler

stream.exceptions(std::ios::goodbit);

pour annuler toutes les exceptions sur le flux et revenir à la recherche d'erreurs.

11
Greg Satir

Vous pouvez également utiliser is_open () pour vérifier si cela a fonctionné, mais! est autorisé (il ne vérifie pas zéro, c'est un spécial surcharge de! )

éditer:
Juste par intérêt - pourquoi cela ne fait-il pas exception?
Est-ce juste que les flux ont été introduits avant les exceptions
ou sommes-nous dans le vieux truc du C++ - ce n'est qu'une erreur pas assez exceptionnelle pour être une exception.

10
Martin Beckett

Votre collègue est faux. Peut-être qu'il a oublié que vous n'écrivez pas C.

Le code est parfait. C'est exactement comment vous devriez vérifier l'état du flux.