Topic: istream weirdness


Author: cpp@netcom.com (Robin Rowe)
Date: 1995/09/25
Raw View
When using istream, numbers aren't parsed consistently by different
compilers. For instance, in g++ inputting "95 09 23" is parsed as
{95,0,9,23}, while the SGI C++ compiler will read it as {95,9,23} as one
would tend to expect. Which is right, and if the former how is this
"feature" turned off to get the latter result? (See test code below.)

A related problem is setw. Given input of "950923" one would like to use
is>>setw(2)>>x to parse it. However, setw has no effect on integers (tried
bc++ 3.1). What is the proper iostream way to accomplish the ubiquitous
task of parsing fixed length numeric fields?

Thanks.

Robin
-----
Robin Rowe       cpp@netcom.com       408-626-6646          Carmel, CA
Rowe Technology  C++ Design/Training  Email for sample C++ Newsletter!

#include <iostream.h>

int main()
{ cout<<"Test cin. CTRL-D or CTRL-Z to quit.\n";
 int x;
 while(cin)
 { cin>>x; //input: "95 09 23" [Enter]
  cout<<x<<endl;
 }
 return 0;
}

/* output g++:

95
0
9
23

*/
/* output SGI:

95
9
23

*/
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: kanze <kanze@lts.sel.alcatel.de>
Date: 1995/09/26
Raw View
In article <446i9t$9m2@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM
(Steve Clamage) writes:

|> In article KAA12047@netcom22.netcom.com, cpp@netcom.com (Robin Rowe) writes:
|> >When using istream, numbers aren't parsed consistently by different
|> >compilers. For instance, in g++ inputting "95 09 23" is parsed as
|> >{95,0,9,23}, while the SGI C++ compiler will read it as {95,9,23} as one
|> >would tend to expect. Which is right, and if the former how is this
|> >"feature" turned off to get the latter result?

|> The question is whether the istream is initialized to decimal conversion
|> mode or not. If initialized to decimal mode, "09" is read as "9". If not,
|> the same rules as for literals in C or C++ is used: a leading "0X" or "0x"
|> means hex conversion, otherwise a leading "0" means octal conversion.
|> Thus, since "9" is not an octal digit, "09" is interpreted as two values,
|> "0" and "9", with istream input.

|> The draft standard section on iostreams is in severe disarray currently,
|> and I can't tell what the default should be. I don't remember what the
|> original AT&T documentation said what the default should be.

|> The solution is simple: set the conversion base explicitly to decimal
|> at program start if you want that as the default
|>  cin.setf(ios::dec, ios::basefield);

I would agree that it is *always* a good idea to set the fmtflags to
the value you want; if nothing else, this makes your code more robust.
(Imagine what happens if someone inserts a debugging output in hex in
front of your output.)

Still, in the public draft (27.4.3.5), it states that after the
constructor for ios_base, ``flags() == skipws | dec''; in table 73,
this corresponds to the scanf conversion %d or %u.  Although I was
unable to find a statement to the effect in the man pages, the cfront
based compilers to which I have access all initialize fmtflags to this
value, too (and I suppose that at least one of them has the original
AT&T implementation).

One thing that does bother me in the standard: suppose I do:

 cout.setf( ios::hex | ios::oct , ios::basefield ) ;

My interpretation of table 73 is that this is fully defined, legal,
and has the same effect as:

 cout.setf( ios::dec , ios::basefield ) ;

Wouldn't it be better if the first form were declared illegal: either
undefined or better, an exception should be thrown?

Obviously, I don't really expect programmers to write the first, but I
do imagine that, separated by many lines of code (or in separate
modules), the following to occur:

 cout.setf( ios::hex ) ;
 //  ...
 cout.setf( ios::oct ) ;

I think that there is a chance for subtle errors here, and would
prefer to at least allow (if not require) the implementation to trap
them.
--

James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: bkline@cortex.nlm.nih.gov (Bob Kline)
Date: 1995/09/29
Raw View
Robin Rowe (cpp@netcom.com) wrote:
.... [snip]
: A related problem is setw. Given input of "950923" one would like to use
: is>>setw(2)>>x to parse it. However, setw has no effect on integers (tried
: bc++ 3.1). What is the proper iostream way to accomplish the ubiquitous
: task of parsing fixed length numeric fields?

Steve Clamage answered the first of your two questions in a separate
article.  As for your second question, you are correct (the task of
parsing fixed-length numeric data is indeed ubiquitous) but unfortu-
nately the draft standard on iostreams does not provide the equivalent
functionality found in the [sf]scanf model (at least it did not in the
version offered for public comment this spring).  The lack has been
pointed out to the committee, and one hopes the defect will be repaired.

--
/*----------------------------------------------------------------------*/
/* Bob Kline                                       Stream International */
/* bob_kline@stream.com               formerly Corporate Software, Inc. */
/* voice: (703) 522-0820 x-311                      fax: (703) 522-5407 */
/*----------------------------------------------------------------------*/
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]