Le code suivant doit copier des données d'un wifstream vers wcout. Une fois que le contenu est copié, le programme jette une exception IOS :: échecs.
#include <string> #include <iostream> #include <sstream> #include <fstream> #include <locale> #include <iterator> #include <algorithm> int main(void) { std::locale::global(std::locale("")); std::wifstream is; is.exceptions( std::ios::failbit | std::ios::badbit ); is.open("test.ts", std::ios::binary); is >> std::noskipws; std::istream_iterator<wchar_t, wchar_t> in(is); std::istream_iterator<wchar_t, wchar_t> end; std::copy(in, end, std::ostream_iterator<wchar_t, wchar_t>(std::wcout)); return 0; }
3 Réponses :
Pour éviter de sauter de l'espace blanc Utilisez le std :: istreambuf_itéator L'exception: p> La locale peut utiliser la facette Codecvt qui échoue. Avez-vous essayé d'imprimer quelles sont les exceptions? P>
Essayez de commenter la ligne locale Voir ce qui se passe. P> try
{
// do work
}
catch(std::exception const& e)
{
std::cout << e.what() << "\n";
}
C'est beau, mais le Noskippws ne provoque pas l'exception. Même si je le décompte, il y a une exception.
Il y a une faute de frappe, le deuxième argument à Istreambuf_iterator est une classe de trait.
Le message d'exception est: basic_ios :: Effacer et même si je supprimais la localisation globale, l'exception est lancée.
parce que vous utilisez Stripping à des essentiels nus et à revenir à un caractère pour le rendre encore plus simple, le programme est équivalent à: P> std :: istream_iterator code>, la tentative de lecture d'un caractère au-delà de l'extrémité du flux définit les deux
eofbit code> et
échecbat code > (Et seulement après que certains bits d'erreur sont définis, l'itérateur est-il égal à l'itérateur final)
#include <iostream>
#include <fstream>
int main()
{
std::ifstream is("test.txt", std::ios::binary);
is.exceptions(std::ios::failbit); // failbit only because that's what you get
is >> std::noskipws;
if(is)
for(char c; is >> c;) // will throw!
std::cout << c;
}
Pas assez équivalent, mais ce serait: pour (char c; est >> c;) COUT << C; CODE>
@Roger Pate aussi loin que je comprends, std :: copier code> n'exécutera pas
opérateur >> code> même une fois si le flux est déjà en échec (et l'itérateur d'entrée est déjà égal. à l'itérateur final) donc tandis que (est).
Selon le §27.6.1.2.3 / 10:
Une fois qu'un objet sentiné est construit, un caractère est extrait de dans em>, si l'on est disponible et stocké dans c em>. Sinon, la fonction appelle in.Setate (écheckit) em>. P> blockQuote>
Donc, lorsqu'il atteint la fin du fichier et ne peut plus extraire un caractère, il définira le bit d'échec, que vous avez défini pour produire une exception. En utilisant
std :: copier code> ne change pas le comportement - un
istream_itéator code> lit via
opérateur >> code>. P>
vous Peut copier le fichier un peu plus facilement: p>
xxx pré> p>
Cela n'a aucun sens pour moi. Si le Streambuf Streambuf retourne TRAITS_TYPE :: EOF (), le flux ne doit définir que le bit EOF, pas le bit d'échec.
Si cela indique que opérateur >> code> reviendrait sans tentative de conversion si le bit EOF a été défini, cela se produirait - mais cela ne le ferait pas. Même si le bit EOF est défini, il tente toujours une conversion, ce qui échoue, de sorte que le bit d'échec est défini.
@cytrinox: Eofbit est défini, puis opt >> causes échecs à définir.
Définir des exceptions de flux semble être une bonne idée, mais cela ne fonctionne souvent pas comme vous vous attendez. Au lieu de cela, vérifiez simplement l'état du flux avant d'utiliser l'entrée, par exemple.
if (flux >> var) {/ * utilisez uniquement Var * /} code>.