c++ - EOF 上的 std::ws 行为
问题描述
我偶然发现了不同编译器之间的行为差异。假设以下代码:
#include <sstream>
#include <iostream>
using namespace std;
int main() {
istringstream ss("100");
int val;
ss >> val;
cout << "fail: " << ss.fail() << " eof: " << ss.eof() << endl;
ss >> std::ws;
cout << "fail: " << ss.fail() << " eof: " << ss.eof() << endl;
}
VS2019 和 Clang 10 使用 libc++ 生成的输出是:
fail: 0 eof: 1
fail: 1 eof: 1
而带有 libstdc++ 的 VS2015 和 GCC 10.2 生成:
fail: 0 eof: 1
fail: 0 eof: 1
所以问题是哪个实现是正确的?std::ws
当 eofbit 已经设置时应该设置失败位吗?
我查过std::ws
标准,上面写着:
30.7.4.4 标准 basic_istream 操纵器 [istream.manip]
模板<class charT, class traits> basic_istream<charT, traits>& ws(basic_istream<charT, traits>& is);
效果:表现为无格式输入函数 (30.7.4.3),但它不计算提取的字符数,也不影响后续调用 is.gcount() 返回的值。在构造一个哨兵对象后,只要下一个可用字符 c 是空格或直到序列中没有更多字符,就会提取字符。空白字符的区分标准与 sentry::sentry (30.7.4.1.3) 使用的标准相同。如果 ws 因为没有更多可用字符而停止提取字符,它会设置 eofbit,但不会设置 failbit。
因此,最后明确声明它设置 eofbit,但在没有可用字符时不设置 failbit。但它也表现为一个未格式化的输入函数,它创建一个sentry
对象。然后sentry
构造函数将is.setstate(failbit)
在is.good()
为 false 时调用。所以在某种程度上,两种实现都不是完全错误的。更好地理解标准的人可以澄清哪种行为是正确的以及我应该在哪里提交错误?
解决方案
failbit
应该设置。它是由sentry
对象完成的,ws
首先是什么构造。
[istream::sentry]/2
explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);
效果:如果is.good()
是false
,则调用is.setstate(failbit)
. 除此以外, ...
推荐阅读
- reactjs - 使用 startAt 和 endAt 的 Firebase 文本搜索在区分大小写时不起作用
- python - 数据框中的重复行添加新的自定义列
- java - 超出内存限制:使用 Java Scanner 时
- .net - dotnetdependensee 对路径的访问被拒绝
- python - 使用 mypy 对方法进行后置条件
- uri - URI 方案的 URI 方案
- reactjs - 如何在 localhost (NextJS) 上运行 web 应用程序的 nrwl/nx 生产版本
- flutter - 如何在 Flutter 中保持状态变化
- c# - 通过 .NET SDK 创建链接的自托管集成运行时
- rust - 为什么在引用时,int lterals 会继续堆?