1

我有一个涉及流的 C++ 课程的编程作业,我试图更好地理解为什么某些函数会以它们的方式工作。

我正在从带有空格的字符串流中读取文本后的输入。为什么最后一个词在输出中重复?

istringstream is;
string inputstring = "The cliched statement regarding the big brown dog and foobar or something    ";
string outputstring;
is.str(inputstring);
while (is.good())
{
    is >> outputstring;
    cout << outputstring << endl;
}

因此,我现在不是在 good 标志上循环,而是将提取作为 while 条件进行:

while (is >> outputstring)
...

这很好用,不会重复最后一句话。这个语句在读完后跳出 while 循环的原因是什么?提取返回对同一流的引用,但它是否检查标志或其他内容?

是否有一个标题可以让您包含所有流?

4

3 回答 3

2

这个语句在读完后跳出 while 循环的原因是什么?提取返回对同一流的引用,但它是否检查标志或其他内容?

提取运算符返回对流的引用是绝对正确的。任何用作while循环控制条件的表达式(还有forand do-while循环和if语句)都被强制bool输入。它算作一次explicit转换,所以ios_base::operator bool()称为,它返回!this->fail(). 这就是检查标志的方式。

于 2012-09-30T16:49:20.737 回答
1

为什么最后一个词在输出中重复?

这就是发生的情况:因为您在 末尾有空格,所以inputstring读取最后一个单词不会翻转 good() 位。程序在最后一个单词后面找到一个空格字符,认为还有更多单词,所以is.good()仍然返回trueis.good()仅当程序尝试读取字符串末尾之后才返回 false;这还没有发生。

然后,下一次你通过循环并从 中读取时is,程序意识到没有更多的单词,不会覆盖 outputstring,因此你再次写入outputstring之前的内容,这是最后一个单词。

尝试打印is.good()读取之前和之后的结果is,并删除末尾的空格字符,inputstring看看有什么变化……</p>

于 2012-09-30T16:40:52.743 回答
0

您总是需要阅读后检查,因为流可能处于良好状态但尝试读取某些内容可能会失败:毕竟,流无法知道您将要阅读的内容。因此,当您检查最后一个元素之后的流时,它仍然是good(). 然后您尝试读取哪个失败并且good()false但是您仍然打印该值。

此外,您希望将.good()其用作条件,因为false即使在读取成功后,如果到达流的末尾,它也可能会变为条件。例如,如果读取了一个数字并且文件末尾的数字后面没有空格,则std::ios_base::eofbit设置。只需像这样使用 idomatic 循环:

while (in >> value) {
    std::cout << "read value='" << value << "'\n";
}

它看起来太简单了以至于无法正确,但实际上做的是正确的事情!

于 2012-09-30T16:41:53.240 回答