简体   繁体   中英

Why doesn't the istringstream eof flag become true when successfully converting a boolean string value to a bool?

I am learning how to convert values stored as a string to native types using istringstream . When a number stored as a string is successfully converted to an int or double , the istringstream eof() function returns true. When a boolean stored as a string is successfully converted to a bool , eof() returns false.

What causes the difference and why does eof() not return true when there seems to be no other characters remaining to process?

Code for converting to a bool:

string value = "true";
istringstream converter(value);
bool convertedValue;

if (!(converter >> std::boolalpha >> convertedValue)){
    cout << "Conversion error." << endl;
} else {
    cout << "Conversion success." << endl;
}

cout << "convertedValue=" << convertedValue << "  value.length()=" << value.length() << "  converter.tellg()=" << converter.tellg() << "  converter.eof()=" << converter.eof() << endl;

The output shows the eof flag is false:

Conversion success.
convertedValue=1  value.length()=4  converter.tellg()=4  converter.eof()=0

Code for converting to a double:

string value = "1234.56";
istringstream converter(value);
double convertedValue;

if (!(converter >> std::boolalpha >> convertedValue)){
    cout << "Conversion error." << endl;
} else {
    cout << "Conversion success." << endl;
}

cout << "convertedValue=" << convertedValue << "  value.length()=" << value.length() << "  converter.tellg()=" << converter.tellg() << "  converter.eof()=" << converter.eof() << endl;

The output shows the eof flag is true:

Conversion success.
convertedValue=1234.56  value.length()=7  converter.tellg()=-1  converter.eof()=1

Code for converting to an int:

string value = "1234";
istringstream converter(value);
int convertedValue;

if (!(converter >> std::boolalpha >> convertedValue)){
    cout << "Conversion error." << endl;
} else {
    cout << "Conversion success." << endl;
}

cout << "convertedValue=" << convertedValue << "  value.length()=" << value.length() << "  converter.tellg()=" << converter.tellg() << "  converter.eof()=" << converter.eof() << endl;

The output shows the eof flag is true:

Conversion success.
convertedValue=1234  value.length()=4  converter.tellg()=-1  converter.eof()=1

I am using g++ (Debian 4.8.3-3) 4.8.3.

The state of "End of File" is reached after the first unsuccessful input operation, where there is nothing more to input.

In the case of reading from a string, an input operation reads one character.

Inputting a boolean ("true") does not have to try and read a character beyond the 'e'. This is in contrast to input operations for numbers, where there may be a next digit.

To determine, whether all has been read: check whether the tellg result is -1 or equal to the string length.

According to the C++ Standard

Successive characters in the range [in,end) (see 23.2.3) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match.

So for example if to compile the following code

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

int main() 
{
    std::istringstream is( "trueabc" );
    bool b = false;

    is >> std::boolalpha >> b;

    std::cout << std::boolalpha << b << std::endl;

    std::cout << is.eof() << std::endl;

    std::string s;

    is >> s;

    std::cout << s << std::endl;

    return 0;
}

using GCC (at www.ideone.com) or MS VC++ 2010 then the result will be the same

true
false
abc

That is it was enough to read "true" from the input stream that to determine the " unique match ".

It is interesting to note that it seems that MS VC++ 2010 contains a bug. If to compile the following code

#include <iostream>
#include <iomanip>
#include <sstream>

int main() 
{
    std::istringstream is( "true" );
    bool b = false;

    is >> std::boolalpha >> b;

    std::cout << std::boolalpha << b << std::endl;

    std::cout << is.eof() << std::endl;


    return 0;
}

then the output will be

MS VC++ 2010:

true
true

GCC:

true
false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM