C++ 为什么';当成功地将布尔字符串值转换为布尔值时,istringstream eof标志是否变为真?
我正在学习如何使用C++ 为什么';当成功地将布尔字符串值转换为布尔值时,istringstream eof标志是否变为真?,c++,c++11,C++,C++11,我正在学习如何使用istringstream将存储为字符串的值转换为本机类型。当存储为字符串的数字成功转换为int或double时,istringstream eof()函数返回true。当存储为字符串的布尔值成功转换为bool时,eof()返回false 造成差异的原因是什么?当似乎没有其他字符需要处理时,为什么eof()不返回true 转换为布尔值的代码: string value = "true"; istringstream converter(value); bool converte
istringstream
将存储为字符串的值转换为本机类型。当存储为字符串的数字成功转换为int
或double
时,istringstream eof()函数返回true。当存储为字符串的布尔值成功转换为bool
时,eof()返回false
造成差异的原因是什么?当似乎没有其他字符需要处理时,为什么eof()不返回true
转换为布尔值的代码:
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;
转换为双精度的代码:
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;
转换为整数的代码:
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;
我使用的是g++(Debian 4.8.3-3)4.8.3。在第一次不成功的输入操作之后,即达到“文件结束”状态,不再需要输入任何内容
在从字符串读取的情况下,输入操作读取一个字符
输入布尔值(“true”)不必尝试读取“e”以外的字符。这与数字输入操作不同,数字输入操作中可能有下一个数字
< P>判断是否已全部读取:根据C++标准检查Telg结果是否为-1或等于字符串长度。< /P> < P> 获得[in,end]范围内的连续字符(见23.2.3) 并与目标序列中的相应位置匹配 仅在必要时确定唯一匹配项 例如,如果要编译以下代码
#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;
}
#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;
}
也就是说,从输入流中读取“true”就足够确定“唯一匹配”
有趣的是,MS VC++2010似乎包含一个bug
#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;
}
#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;
}
GCC:
true
true
true
false
为什么要在istringstream中检查eof?!我试图找到一种可靠的方法来测试转换是否使用了整个值,或者忽略了其中的一部分(如将双精度读入整数)。要检查这一点,我当前使用的是
if(!converter.eof()&&&(converter.tellg()!=value.length())
因为eof不适用于bool类型,我真的很好奇为什么。@user3371448看到了我的答案。它更详细。从最好的例子中学习,看看Boost的词法转换()
函数。你会发现他们提取了一个额外的std::ws
,它将跳过空白,然后检查eof。因为tellg()返回pos_类型,length()返回size_类型,强制转换或执行比较的最安全方式是什么?我刚刚注意到在编译时出现了“有符号和无符号整数表达式之间的类型比较”警告。这是有意义的。当tellg()时,我没有看到eof=1的模式=-1.是否总是这样?在读取第一次之前,tellg应该返回0。在最后一次读取之前,它应该是长度-1,在最后一次读取之后是长度。因此,在一次读取失败后,它会转到-1,tellg的结果不能用于seekg,因为设置了eofbit标志。
true
true
true
false