gpt4 book ai didi

c++ - std::ws 应该在文件末尾引发 failbit 吗?

转载 作者:可可西里 更新时间:2023-11-01 16:38:52 31 4
gpt4 key购买 nike

是否应该使用 std::ws 操纵器从流中提取失败位?在以下代码中,Clang 编译的(在 Xcode 4.5.1 中)程序最终断言失败。显然 s >> std::ws 在 EOF 导致失败。然而 GCC 4.7.2 通过了断言。哪个是正确的?

#include <iostream>
#include <sstream>
#include <cassert>

int main(int argc, const char * argv[])
{
{
// Read string with trailing ws.
std::istringstream s( "test " );
std::string test;

s >> std::ws;
assert( !s.fail() ); // No ws to skip, but no failure.

s >> test;
assert( test == "test" );
assert( !s.fail() );

s >> std::ws;
assert( !s.fail() ); // No prob skipping trailing ws.
}
{
// Retry with no trailing ws.
std::istringstream s( "test" );
std::string test;

s >> std::ws;
assert( !s.fail() ); // No ws to skip, but no failure.

s >> test;
assert( test == "test" );
assert( !s.fail() );

s >> std::ws;
assert( !s.fail() ); // CLANG: Skipping absent ws at eof raises failbit.
}

return 0;
}

最佳答案

我相信 libc++ 正确地实现了标准。

[ 我引用的是 N3290,它是 C++11 标准草案。 C++14 不会改变这一点。 ]

ws 在 [istream.manip] 中描述:

Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), except that it does not count the number of characters extracted and does not affect the value returned by subsequent calls to is.gcount(). After constructing a sentry object extracts characters as long as the next available character c is whitespace or until there are no more characters in the sequence. Whitespace characters are distinguished with the same criterion as used by sentry::sentry (27.7.2.1.3). If ws stops extracting characters because there are no more available it sets eofbit, but not fail bit.

此处确定正确行为的关键短语是“在构造哨兵对象之后”。

哨兵对象在 [istream::sentry] 中描述,那里的文本开始...

1 The class sentry defines a class that is responsible for doing exception safe prefix and suffix operations.

explicit sentry(basic_istream& is, bool noskipws = false);

2 Effects: If is.good() is false, calls is.setstate(failbit). Otherwise, prepares for formatted or > unformatted input. ...and so on...

这是唯一可用的哨兵构造函数,因此也是 libc++ 使用的构造函数。

所以失败位在提取任何字符之前被设置,所以段落末尾的文本不适用。如果流包含 ""(即最后一个空格),则调用 std::ws 不会设置失败位,只是 eof(这是什么OP 预计会发生)。

关于c++ - std::ws 应该在文件末尾引发 failbit 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13423514/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com