1

当我尝试使用从输入中提取有效数字时,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要这样做,如何避免这种情况?

4

2 回答 2

3

这是因为您从流中读取数字。

运算符从流中>>提取"3rd",并尝试将其转换为 a double,但由于只有字符串的第一个字符是数字,它只能解析"3"并简单地丢弃非数字字符。

如果需要"3rd",则需要将其作为字符串读取。

于 2014-12-11T11:21:48.767 回答
0

运算符只在>>流中尽可能多地读取,留下任何剩余的字符。因此:

std::istringstream( temp ) >> x

只会提取3if tempcontains 3rd,留下 rd. 为了确保整个字段都被读取,你需要确保你在最后:

std::istringstream fieldParser( temp );
if ( fieldParser >> x && fieldParser.peek() == EOF ) {
    // ...
}

例如。(更一般地说,您需要将 a 附加>> std::ws 到输入链的末尾,以跳过任何尾随空格。但是,在您的情况下,由于您temp使用了>> 运算符,因此可以保证它不包含空格。 )

FWIW:在这种特殊情况下,我会使用strtod

errno = 0;
const char* end;
x = strtod( temp.c_str(), &end );
if ( errno != 0 || *end != '\0' ) {
    //  Error occured...
}

但是,无论哪种方式,您都不能一次完成if;你之前需要额外的代码。

于 2014-12-11T12:09:12.593 回答