152 votes

Restaure l'état de std :: cout après l'avoir manipulé

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 original après son retour de la fonction. (Un peu comme std :: boolalpha et std :: noboolalpha ..)?

Merci, Iyer

134voto

Stefan Kendall Points 28274

Googling m'a donné ceci:

   ios::fmtflags f( cout.flags() );

  //Your code here...

  cout.flags( f );
 

Vous voudrez probablement mettre cela en tête et à la fin de votre fonction.

64voto

Chris Jester-Young Points 102876

Le Boost IO Stream State Saver semble exactement ce dont vous avez besoin. :-)

Exemple basé sur votre extrait de code:

 void printHex(std::ostream& x) {
    boost::io::ios_flags_saver ifs(x);
    x << std::hex << 123;
}
 

24voto

qbert220 Points 5029

J'ai créé un RAII classe à l'aide de l'exemple de code à partir de cette réponse. Le gros avantage de cette technique vient, si vous avez plusieurs voies du retour d'une fonction qui définit des indicateurs sur une iostream. Selon la voie de retour est utilisé, le destructeur sera toujours appelé les drapeaux et l'obtiendrez toujours le réinitialiser. Il n'y a aucune chance d'oublier de restaurer les drapeaux lorsque la fonction retourne.

class IosFlagSaver {
public:
    explicit IosFlagSaver(std::ostream& _ios):
        ios(_ios),
        f(_ios.flags()) {
    }
    ~IosFlagSaver() {
        ios.flags(f);
    }

    IosFlagSaver(const IosFlagSaver &rhs) = delete;
    IosFlagSaver& operator= (const IosFlagSaver& rhs) = delete;

private:
    std::ostream& ios;
    std::ios::fmtflags f;
};

Vous pouvez alors l'utiliser par la création d'une instance locale de IosFlagSaver chaque fois que vous vouliez enregistrer le courant de l'état du pavillon. Lorsque cette instance est hors de portée, l'état du pavillon sera restauré.

void f(int i) {
    IosFlagSaver iosfs(std::cout);

    std::cout << i << " " << std::hex << i << " ";
    if (i < 100) {
        std::cout << std::endl;
        return;
    }
    std::cout << std::oct << i << std::endl;
}

9voto

whacko__Cracko Points 1942

Avec un peu de modification pour rendre la sortie plus lisible:

  void printHex(std::ostream& x){
     ios::fmtflags f(x.flags());
     x<<std::hex<<123<<"\n";
     x.flags(f);
  }


 int main(){
      std::cout<<100<<"\n"; // prints 100 base 10
      printHex(std::cout); //prints 123 in hex
      std::cout<<73<<"\n"; //problem! prints 73 in hex..
  }
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X