Why does insertion in streams reset the width to 0?

Insertion seems to be causing the stream to reset its width to 0. In other words, you have to call width () multiple times when you want to align your output, which makes me wonder why. I looked through the C ++ 11 standard and I found a partial answer that assumes width (0) is called inside character insertion according to ISO C ++ standard ยง27.7.3.6.4.1. However, this is just a subset of the inserts, which is not a complete answer. Then what about arithmetic insertions ? I couldn't find any other links that could explain the behavior of streams.

+3


source to share


1 answer


Because that is how streams were specified. The statement <<

width

must be reset, other formatting parameters no. I can only guess why: presumably for things like:

std::cout << std::setw(8) << someValue << " cm";

      

You wouldn't want the width to be applied to the line " cm"

, for example. But you would like to be able to write:

std::cout << std::setw(8) << price << " | " << setw(20) << article;

      

where article

is a string.

Except of course you would need to change the justification before the string to do this as well, and changing the justification be sticky affecting the next numeric output.

In practice, of course, experienced programmers don't write this kind of code. They will use something like:

std::cout << price(column1Width) << article.price
    << " | " << label(column2Width) << article.name;

      



(assuming they had to create tables with fixed font width anyway). Where price

and label

are manipulators that set any number of format flags and restored them in its destructor. (Since they are temporary, their destructor will be named at the end of the full expression.) So this particular line of code doesn't say anything about physical formatting, but rather that the first value should be formatted as a price and the second as a label. (And from Of course, if someone above decides that prices or labels should be formatted differently, you're just changing the manipulators, not looking for all the output operators and trying to figure out which prices and which aren't.)

EDIT (added links to standard):

It is important to note that the standard cannot cover everything here, as most of the time you will be using a custom operator<<

one written by the author of your chosen class. Most builtins are operator<<

covered in ยง22.4.2.2.2 in the description of stage 3:

If it is str.width()

nonzero, and the number of charTs in the sequence after step 2 is less than str.width()

, then it is enough to pad characters to be added to the sequence at the position specified for padding so that the length of the sequence is up to str.width()

.

str.width(0)

...

For C style characters and strings, this is specified (in most cases) in ยง27.7.3.6.4. For std::string

, see ยง 21.4.8.8.

For std::complex

: the standard defines insertion in terms of other input operators. Thus, any setting width

will only affect the valid item. (Practically, I think we can see this broken. When I implemented the pre-standard complex class, mine <<

checked the width, and if it was non-zero, subtracted 3 for non-numeric fields, then divides by 2 and sets them before outputting each double. I don't I'm sure this is correct, but it is certainly better than what the standard indicates. And I also used a half-line as a separator if the decimal point was a comma, as in most places I've lived.)

The fact that the other formatting options remain unchanged is that nothing is specified in the standard, and additional side effects other than those specified are considered prohibited.

In all cases, the spec says what is being called stream.width(0)

. But in the standard, each case is listed separately. There isn't (even for intent) any general rule I can find here. Traditionally, however, the rule has always been: reset the width and leave the others unchanged. The Principle of Least Surprise says you should do this for the user <<

(s >>

).

+2


source







All Articles