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.