当我尝试使用istringstream
从输入中提取有效数字时,我从istringstream
获得了以下不当行为:
例如:
void extract(void)
{
double x;
string line, temp;
getline(cin, line);
istringstream is(line);
while(is >>temp)
{
if(istringstream(temp) >>x)
{std::cout<<"number read: "<<x<<endl;}
}
}
输入:
1 2 3rd 4th
输出:
number read: 1
number read: 2
number read: 3
number read: 4
错误行为是istringstream将字符串3rd
转换为数字3
为什么istringstream
会这样做?如何避免这种情况?
答案 0 :(得分:3)
这是因为您从流中读取数字。
>>
运算符从流中提取"3rd"
,并尝试将其转换为double
,但由于只有字符串的第一个字符是数字,因此它只能解析"3"
并简单地丢弃非数字字符。
如果你想要 "3rd"
,那么你需要把它作为一个字符串来读。
答案 1 :(得分:0)
>>
运算符只能在流中读取尽可能多的内容,
留下任何剩余的角色。因此:
std::istringstream( temp ) >> x
如果3
包含temp
,则仅会提取3rd
rd
。为了确保整个字段已被读取,
你需要确保你到最后:
std::istringstream fieldParser( temp );
if ( fieldParser >> x && fieldParser.peek() == EOF ) {
// ...
}
例如,。 (更一般地说,您需要附加>> std::ws
到输入链的末尾,跳过任何尾随的空格。
但是,在您的情况下,因为temp
使用>>
运算符,保证它不包含空格。)
FWIW:在这个特殊情况下,我会使用strtod
:
errno = 0;
const char* end;
x = strtod( temp.c_str(), &end );
if ( errno != 0 || *end != '\0' ) {
// Error occured...
}
但是,无论哪种方式,你都不能在一个if
中完成;你会
之前需要额外的代码。