Topic: Defect: unexpected output required of strings.


Author: James Kanze <james.kanze@gmail.com>
Date: Fri, 23 Jul 2010 13:23:42 CST
Raw View
What should the following code output?

   #include <string>
   #include <iostream>
   #include <iomanip>

   int
   main()
   {
       std::string test("0X1Y2Z");
       std::cout.fill('*');
       std::cout.setf(std::ios::internal, std::ios::adjustfield);
       std::cout << std::setw(8) << test << std::endl;
   }

I would expect "**0X1Y2Z", and this is what the compilers I have
access to (VC++, g++ and Sun CC) do.  But according to the
standard, it should be "0X**1Y2Z":

[string.io]/5:

   Effects: [operator<< of std::basic_string] Behaves as
   a formatted output function ([ostream.formatted.reqmts]).
   After constructing a sentry object, if this object
   returns true when converted to a value of type bool,
   determines padding as described in
      [facet.num.put.virtuals], then inserts the resulting
   sequence of characters seq as if by calling
   os.rdbuf()->sputn(seq, n), where n is the larger of
   os.width() and str.size(); then calls os.width(0).

[facet.num.put.virtuals]/5:

      [...]
   Stage 3: A local variable is initialized as fmtflags
   adjustfield= (flags & (ios_base::adjustfield)); The
   location of any padding is determined according to
   Table 88.

                          Table 88 =97 Fill padding
                         State                            Location
       adjustfield == ios_base::left                   pad after
       adjustfield == ios_base::right                  pad before
       adjustfield == internal and a sign occurs in    pad after the
sign
       the representation
       adjustfield == internal and representation      pad after x or
X
       after stage 1 began with 0x or 0X
       otherwise                                       pad before

   If str.width() is nonzero and the number of charT=92s in
   the sequence after stage 2 is less than str.width(),
   then enough fill characters are added to the sequence at
   the position indicated for padding to bring the length
   of the sequence to str.width().

   str.width(0) is called.

Although it's not 100% clear what "the sequence after stage 2"
should mean here, when there is no stage 2, the only reasonable
assumption is that it is the contents of the string being
output.  In the above code, the string being output is "0X1Y2Z",
which starts with "0X", so the padding should be inserted "after
x or X", and not before the string.

I believe that this is a defect in the standard, and not in the
three compilers I tried.

--
James Kanze


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]