1

Why does

#include <iostream>
#include <iomanip>

int main()
{
    std::cout << std::fixed << std::setw(4) << std::setprecision(0);
    std::cout << 4;
    std::cout << 4;
}

print

"   44

(ignore the quote, it's just to get the formatting right) and not

"   4   4

?

I thought that the iostream 'modifiers' persistent on the stream until they are explicitly changed/reset. I have a bunch of numbers I need to print with a certain prefix so that all fields have equal width; should I re-apply my modifiers every time I print one? Doesn't seem very efficient.

Roel
  • 19,338
  • 6
  • 61
  • 90
  • 1
    Some modifiers are persistent and others not, whether it is efficient or not is now irrelevant since it cannot possibly be changed anymore. – Passer By Sep 07 '17 at 10:39

1 Answers1

4

Unfortunately you've wandered into one of the areas of the standard that's a little archaic and seemingly without any overarching design goals.

This is undoubtedly historic as the iostreams library AFAIAA, was not originally part of the STL which is what became the standard library.

It's worth reading the notes on all std::ios_base members and the associated manipulators.

For example:

http://en.cppreference.com/w/cpp/io/ios_base/width

Some I/O functions call width(0) before returning, see std::setw (this results in this field having effect on the next I/O function only, and not on any subsequent I/O)

The exact effects this modifier has on the input and output vary between the individual I/O functions and are described at each operator<< and operator>> overload page individually.

Anticipating:

But that's just <insert expletive>!!!

A: yup.

Community
  • 1
  • 1
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • Oh right, I thought I was just missing something. Thanks. – Roel Sep 07 '17 at 12:37
  • One additional question maybe: is it possible to make my own version of setw() (say, setw_persistent()) that doesn't call width(0)? I mean, it would involve making a custom overload for << as described here https://stackoverflow.com/questions/29337774/how-are-iomanip-functions-implemented but I mean, what does the overload for setw() do on the stream? – Roel Sep 07 '17 at 12:44
  • @Roel If it was worth playing around with, cleverer people than you or me would have already provided it in boost. It's just one of those things that isn't worth wasting time on. Better to just learn the interface and use that - or use something more expressive, like boost::format, which I can thoroughly recommend. I think that the whole streaming operator thing was badly conceived many many years ago, before people knew better. – Richard Hodges Sep 07 '17 at 12:53