[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
A problem with cin or strtod?
From: |
Daniel P. Katz |
Subject: |
A problem with cin or strtod? |
Date: |
09 Feb 2001 13:28:14 -0500 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 |
Hi.
I ran into a problem where (cin >> x) for double x reads in
NaN as a double, even though this seems not to be in accordance with
the C++ standard. It seems to me that the problem is either with cin
(in g++) or strtod(3) (in glibc), and since I don't have the C and C++
standards in front of me, I'm not quite sure which of them is the
problematic element. Therefore, I am sending this to the bug streams
for both g++ and glibc.
I began with the following code to read names and student grades and
just print them out again:
-------------------------------------------------------
address@hidden:~/ac++/ch05/5-2$ cat data
Smith 93 91 47 90 92 73 100 87
Carpenter 75 90 87 92 93 60 0 98
nand 78 66 65 69 64 68 63 61
Foo 33 45 66 67 43 42 31 16
Nancy 12 23 34 34 45 14 23 12
-------------------------------------------------------
-------------------------------------------------------
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main()
{
string name;
while (cin >> name) {
cout << name << " "; // print the student's name
if (cin) {
double x;
while (cin >> x) // print out all the doubles as grades
cout << x << " ";
cin.clear(); /* reset the stream (should be in an
error state from trying to read a
non-double) */
}
cout << endl;
}
return 0;
}
-------------------------------------------------------
Upon compilation and running, I get:
-------------------------------------------------------
address@hidden:~/ac++/ch05/5-2$ g++ -Wall -ansi -pedantic \
> -o error.out error_harness.cpp
address@hidden:~/ac++/ch05/5-2$ ./error.out < data
Smith 93 91 47 90 92 73 100 87
Carpenter 75 90 87 92 93 60 0 98 nan
d 78 66 65 69 64 68 63 61
Foo 33 45 66 67 43 42 31 16 nan
cy 12 23 34 34 45 14 23 12
-------------------------------------------------------
Clearly, the cin istream is reading "Nan" as an acceptable value for a
double.
I corresponded with Andrew Koenig about this example (the code
above was derived from some of the sample code in his book
_Accelerated C++_) and his response led me to look at strtod(3):
So what I think is happening is that the Linux implementation
(I think that g++ uses that native C libraries for I/O
conversions) is treating "Nan" as a number as an
``extension.'' I put ``extension'' as quotes, because when I
searched through the C++ standard, I came to the conclusion
that a conforming implementation is not permitted to extend
the language in this way.
In particular, conforming implementations are expect to accept
all valid input, and reject all invalid input. In this case,
valid input is actually defined by the strtod function in the
C library, which requires that the input contain at least one
digit and begin with a digit, +, -, or decimal point.
C++ does offer a mechanism for extending the definition of
input to accept strings such as "NaN". One does so by
defining a data structure called a locale, and the telling cin
to use that locale instead of the standard one. But for it to
accept this particular input without an explicitly defined
locale is, as far as I know, an unauthorized change to the
specification.
As far as I can tell, I am using the default "C" locale.
Based on this, it is not clear to me whether the issue is with
the conformance of strtod(3) to the C standard, or the usage of
strtod(3) by g++ in the implementation of cin. I would hope, however,
that compiling with the -ansi and -pedantic flags would be enough to
get the correct, standard behavior. (I admit that I don't have the
C++ standard in front of me, but if Dr. Koenig says that this behivior
doesn't conform then I'm inclined to take his word for it! :-))
I hope this helps lead either glibc or g++ closer to standard
behavior. Thanks.
Dan Katz
P.S. System info: Debian testing/woody
address@hidden:~$ uname -a
Linux magellan 2.2.18 #1 Thu Dec 21 21:13:10 EST 2000 i686 unknown
address@hidden:~$ g++ --version
2.95.2
address@hidden:~$ strings /lib/libc.so.6 | grep version
[...]
GNU C Library stable release version 2.2.1, by Roland McGrath et al.
Compiled by GNU CC version 2.95.2 20000220 (Debian GNU/Linux).
- A problem with cin or strtod?,
Daniel P. Katz <=