C++ - How to reset the output stream manipulator flags [duplicate]
Asked Answered
D

5

30

I've got a line of code that sets the fill value to a '-' character in my output, but need to reset the setfill flag to its default whitespace character. How do I do that?

cout << setw(14) << "  CHARGE/ROOM" << endl;
cout << setfill('-') << setw(11) << '-' << "  " << setw(15) << '-' << "   " << setw(11) << '-' << endl;

I thought this might work:

cout.unsetf(ios::manipulatorname) // Howerver I dont see a manipulator called setfill

Am I on the wrong track?

Donegal answered 3/10, 2009 at 12:33 Comment(0)
I
36

You can use copyfmt to save cout's initial formatting. Once finished with formatted output you can use it again to restore the default settings (including fill character).

{
    // save default formatting
    ios init(NULL);
    init.copyfmt(cout);

    // change formatting...
    cout << setfill('-') << setw(11) << '-' << "  ";
    cout << setw(15) << '-' << "   ";
    cout << setw(11) << '-' << endl;

    // restore default formatting
    cout.copyfmt(init);
}
Illsuited answered 19/9, 2014 at 21:47 Comment(4)
Surprised nobody posted this earlier :) Rolling it into an RAII guard would be good though, in case an exception is thrown. Have run into that issue in a logging framework.Cordes
Is that working on all systems? When I try it, my std::cout refuses to output anything after...ever!Straighten
this is great! it works also for std::hexScleroderma
Here you have RAII simple impl: github.com/gelldur/gcpp/blob/master/src/gcpp/stream/…Racecourse
C
31

Have a look at the Boost.IO_State_Savers, providing RAII-style scope guards for the flags of an iostream.

Example:

#include <boost/io/ios_state.hpp>

{
  boost::io::ios_all_saver guard(cout); // Saves current flags and format

  cout << setw(14) << "  CHARGE/ROOM" << endl;
  cout << setfill('-') << setw(11) << '-' << "  " << setw(15) << '-' << "   " << setw(11) << '-' << endl;
// dtor of guard here restores flags and formats
}

More specialized guards (for only fill, or width, or precision, etc... are also in the library. See the docs for details.

Cheops answered 3/10, 2009 at 13:45 Comment(3)
Great answer, should be the accepted one.Fipple
@gd1: Good answer, but not great, as I have to include Boost just to save the iostream flags.Erbes
@Isaac: in C++, it seems to me that you either use boost or end up reimplementing it, or wait for Boost.Something to be included in the standard.Fipple
R
10

You can use the ios::fill() function to set and restore the fill character instead.

http://www.cplusplus.com/reference/iostream/ios/fill/

#include <iostream>
using namespace std;

int main () {
  char prev;

  cout.width (10);
  cout << 40 << endl;

  prev = cout.fill ('x');
  cout.width (10);
  cout << 40 << endl;

  cout.fill(prev);

  return 0;
}
Regiment answered 3/10, 2009 at 12:40 Comment(1)
This is correct, but you need to do the same thing with width too.Mercola
B
3

You can manually change the setfill flag to whatever you need it to be:

float number = 4.5;
cout << setfill('-');
cout << setw(11) << number << endl; // --------4.5
cout << setfill(' ');
cout << setw(11) << number << endl; // 4.5
Bragdon answered 7/7, 2015 at 17:13 Comment(1)
That sets it to ' ', which may or may not be the value it had before the first setfill.Paley
S
-2

The null character will reset it back to the original state: setfill('\0')

Synchrotron answered 20/5, 2017 at 21:52 Comment(1)
The original state is not necessarily the previous state. Besides, where is this claimed function of '\0' documented? All I can see are statements that setfill() just takes a char, with no special meaning for it. So you would be setting the fill character to NUL, which is not going to be what it originally was and is not going to be very useful at all. Or did I miss something in the Standard that makes it work?Boldt

© 2022 - 2024 — McMap. All rights reserved.