Supposons que j'ai un code comme celui-ci:
void printHex(std::ostream& x){
x<<std::hex<<123;
}
..
int main(){
std::cout<<100; // prints 100 base 10
printHex(std::cout); //prints 123 in hex
std::cout<<73; //problem! prints 73 in hex..
}
Ma question est de savoir s'il existe un moyen de «restaurer» l'état de cout
à son état d' origine après le retour de la fonction? (Un peu comme std::boolalpha
et std::noboolalpha
..)?
Merci.
Réponses:
vous devez
#include <iostream>
ou#include <ios>
alors si nécessaire:Vous pouvez les mettre au début et à la fin de votre fonction, ou consultez cette réponse pour savoir comment l'utiliser avec RAII .
la source
L' économiseur d'état Boost IO Stream semble exactement ce dont vous avez besoin. :-)
Exemple basé sur votre extrait de code:
la source
ios_flags_saver
sauvegarde et définit simplement les indicateurs comme dans la réponse de @ StefanKendall.ios_flags_saver
une seule.Notez que les réponses présentées ici ne restaureront pas l'état complet de
std::cout
. Par exemple,std::setfill
"collera" même après avoir appelé.flags()
. Une meilleure solution consiste à utiliser.copyfmt
:Imprimera:
plutôt que:
la source
std::ios
soit toujours en mauvais état car il aNULL
rdbuf. Ainsi, la définition d'un état avec des exceptions activées entraîne la levée d'exceptions en raison d'un mauvais état. Solutions: 1) Utilisez une classe (par exemplestd::stringstream
) avecrdbuf
set au lieu destd::ios
. 2) Enregistrez l'état des exceptions séparément dans la variable locale et désactivez-les avantstate.copyfmt
, puis restaurez l'exception à partir de la variable (et recommencez après la restauration de l'état à partiroldState
duquel les exceptions sont désactivées). 3) Situérdbuf
àstd::ios
comme ceci:struct : std::streambuf {} sbuf; std::ios oldState(&sbuf);
J'ai créé une classe RAII en utilisant l'exemple de code de cette réponse. Le gros avantage de cette technique vient si vous avez plusieurs chemins de retour à partir d'une fonction qui définit des indicateurs sur un iostream. Quel que soit le chemin de retour utilisé, le destructeur sera toujours appelé et les indicateurs seront toujours réinitialisés. Il n'y a aucune chance d'oublier de restaurer les drapeaux lorsque la fonction revient.
Vous l'utiliseriez ensuite en créant une instance locale de IosFlagSaver chaque fois que vous vouliez enregistrer l'état actuel du drapeau. Lorsque cette instance sort du champ d'application, l'état du drapeau est restauré.
la source
Avec un peu de modification pour rendre la sortie plus lisible:
la source
Vous pouvez créer un autre wrapper autour du tampon stdout:
Dans une fonction:
Bien sûr, si les performances sont un problème, cela coûte un peu plus cher car il copie l'
ios
objet entier (mais pas le tampon), y compris certains éléments pour lesquels vous payez mais qu'il est peu probable que vous utilisiez, comme les paramètres régionaux.Sinon, j'ai l'impression que si vous allez l'utiliser,
.flags()
il vaut mieux être cohérent et utiliser.setf()
aussi plutôt que la<<
syntaxe (pure question de style).Comme d'autres l'ont dit, vous pouvez mettre les éléments ci-dessus (et
.precision()
et.fill()
, mais généralement pas les éléments relatifs aux paramètres régionaux et aux mots qui ne seront généralement pas modifiés et qui sont plus lourds) dans une classe pour plus de commodité et pour la rendre sûre pour les exceptions; le constructeur doit accepterstd::ios&
.la source
std::stringstream
pour la partie mise en forme comme l'a souligné Mark Sherred .std::stringstream
est unstd:ostream
, sauf que l'utilisation de l'un introduit un tampon intermédiaire supplémentaire.std:stringstream
va créer son propre indépendantstd:stringbuf
(unstd::streambuf
dérivé), qui doit ensuite être versé dansstd::cout.rdbuf()
Je voudrais généraliser quelque peu la réponse de qbert220:
Cela devrait également fonctionner pour les flux d'entrée et autres.
PS: J'aurais aimé faire ceci simplement un commentaire à la réponse ci-dessus, stackoverflow ne me permet cependant pas de le faire à cause d'une réputation manquante. Alors faites-moi encombrer les réponses ici au lieu d'un simple commentaire ...
la source