0

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

#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;
}
4

3 回答 3

2

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

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

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

如果您使用连接到控制台的流(例如),您的呼叫>>会如您预期的那样被阻止。的行为stringstream不同(你不能指望奇迹般地包含更多数据)

于 2012-06-20T18:17:24.177 回答
0

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

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

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

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

于 2012-06-20T18:18:30.817 回答
0

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

通过直接评估这个表达式来检查值的提取是否成功: if (iss >> c),但不要考虑调用iss.good(). 检查这个答案并看看:
那个时髦的 while (std::cin >> foo) 语法是如何工作的?
为什么我的输入似乎处理超过文件末尾?

于 2012-06-20T18:21:09.990 回答