从istringstream读取时出现意外行为

时间:2012-06-20 18:09:45

标签: c++ string iostream istringstream

我对流行为有疑问,请参阅以下示例。我期待的是,因为字符串中只有5个字符,所以当我尝试读取10个字符时,流读取将被卡住。相反,输出是“hellooooo”...最后一个char重复。 我的问题有两个方面:第一,为什么?第二,无论如何都要使流表现得好像不再重复最后一个字符?

#include <sstream>
#include <iostream>
using namespace std;

int main(void) {
    char c;
    string msg("hello");
    istringstream iss(msg);
    unsigned int i = 0;
    while (i < 10) {
        iss >> c;
        cout << c;
        i++;
    }
    cout << endl;
    return 0;
}

3 个答案:

答案 0 :(得分:2)

你看到的是在一个错误的状态下读取流的结果。当你读过流中的最后一个元素(这是一个字符串流)时,流变得错误,任何其他从它读取的尝试都将失败(并保持提取变量不变)。

在进一步阅读之前,您必须检查提取操作是否成功:

if (iss >> c) {
  // succeess
} else {
  // failed to extract, handle error
}

如果您使用连接到控制台的流(例如),您对>>的呼叫会按预期阻止。 stringstream的行为是不同的(您不能期望微不足道地包含更多数据)

答案 1 :(得分:0)

原因是当您读到流的末尾时,所有读取后的尝试都会失败,并在c中读取最后一个值。

如果您想阅读最多 10个字符:

while (i < 10 && is >> c) {
    cout << c;
    i++;
}

这是有效的,因为流可以转换为bool,如果流处于“良好”状态,则为true

答案 2 :(得分:0)

“最后一个字母重复”
iss >> c失败时,c保持不变。

通过直接评估此表达式来检查值的提取是否成功:if (iss >> c),但甚至考虑调用iss.good()。检查this answer并查看:
How does that funky while (std::cin >> foo) syntax work?
Why does my input seem to process past the end of file?