operator>> for numbers: stream state after failed read

H

heplesser

Summary:
Does the C++ standard require
std::basic_istream<>::eek:perator>>(double&) to leave the input stream
untouched in case of a read failure?

Details:
I noticed an unexpected behavior of operator>>() for numbers (double,
int) when reading from cin. I would like to ask for expert
clarification on whether I am misunderstanding the rules of the game,
or whether my library implementation has a bug. I tested this on g++
4.1.1 under Linux, g++ 3.4.5 MinGW and cxx 7.1 under Tru64 Unix
(behavior there is slightly different than described below). I checked
Josuttis "The C++ Standard Library" and the C++ standard ch 22.2.2 and
27.6.1, but haven't been able to get anything useful out of them.

The problem is as follows: If would like to read sequences like "1 2
+" by first trying to read into a double, and if that fails try to
read into a char, see sample program below (the program reads only a
single number/symbol). This works fine as long as any non-number token
is not a symbol that could be the first symbol in a number, i.e. the
plus sign, the minus sign or the decimal point. If the symbol is one
of those three, the program simply hangs. If I change the locale to,
e.g., Norwegian, it will hang on the decimal comma instead of the
decimal point.

My interpretation is that the operator reads +, -, or ., then tries to
read the next digit, which it does not find, and then raises the
failbit and returns WITHOUT putting +, -, or . back into the input
stream. Should this/must this be so?

A work-around presumably is to read to a string, place it into a
stringstream and then extract from the latter.

I'd appreciate expert advice on this.
Hans

/*
Illustrate problems with symbols that can
be prefixes to numbers (+,-,. if no locale is set).

If a number is entered on the keyboard, the program prints
OK --- double: -1.3

If any characted but + - . is entered, the program prints
FAIL --- double
OK --- char: a

If + - or . are entered, the program hangs after
FAIL --- double
*/

#include <iostream>
using namespace std;


int main()
{
double x = 0;
char c = 0;

if ( cin >> x )
cerr << "OK --- double: " << x << endl;
else
{
cerr << "FAIL --- double" << endl;;
cin.clear();
if ( cin >> c )
cerr << "OK --- char: " << c << endl;
else
cerr << "FAIL --- char" << endl;
}

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,836
Latest member
login dogas

Latest Threads

Top