为什么即使'ss.fail()'为真后循环终止(这里's'是一个字符串流对象)?

时间:2013-08-17 09:15:39

标签: c++ stringstream

以下代码:

int main() {
    stringstream ss;
    string str;
    str = "999:97 42:22 44:102300";
    ss << str;
    char ch;
    int temp, temp1;
    while (1) {
        if (ss.fail()) {
    break;
    }
    ss >> temp >> ch >> temp1;
    cout << temp << ":" << temp1 << endl;
    }
    return 0;
}

这给出了以下输出:

999:97
42:22
44:102300
44:102300

以下是一个链接:http://ideone.com/cC75Sk

我只是想知道,为什么代码不会在break语句之后结束?

2 个答案:

答案 0 :(得分:3)

您可以修改您的程序,如

int main() 
{
    stringstream ss;
    string str;
    str = "999:97 42:22 44:102300";
    ss << str;
    char ch;
    int temp, temp1;
    while (ss >> temp >> ch >> temp1) 
    {
        cout << temp << ":" << temp1 << endl;
    }
    cin.ignore();
}

您的代码无法正常工作,因为在第三次迭代中,读取正常并且没有设置失败标志,它在读取失败时设置,即在第4次迭代尝试时设置。

由于读取失败,缓冲区仍然具有旧值,这些值将被打印(现在在第5次迭代中失败,因为它在第4次失败时返回true)

答案 1 :(得分:1)

因为它没有失败,简单就是这样。阅读是成功的,但你错误地检查错误太晚了。

在使用您阅读的对象之前,您必须检查fail条件,否则您将面临处理无效数据的风险。你可以这样写循环:

while (1) {
    ss >> temp >> ch >> temp1;
    if (ss.fail()) break;
    cout << temp << ":" << temp1 << endl;
}

但这种惯用的方法是在@ Shaksham的回答中。