配置std::istringstream
以在设置failbit
时抛出异常后,我发现libc ++没有异常(这是在Linux下使用libc ++编译并在libcxxrt的支持下编译)。我想这是libc ++或libcxxrt中的一个错误:
#include <iostream>
#include <sstream>
template<typename T> std::istream &getvalue(std::istream &is, T &value, const T &default_value = T())
{
std::stringstream ss;
std::string s;
std::getline(is, s, ',');
ss << s;
if((ss >> value).fail())
value = default_value;
return is;
}
int main()
{
std::string s = "123,456,789";
std::istringstream is(s);
unsigned n;
try
{
is.exceptions(std::ios::failbit | std::ios::eofbit);
getvalue(is, n);
std::cout << n << std::endl;
getvalue(is, n);
std::cout << n << std::endl;
// Disable EOF exception on last bit
is.exceptions(std::ios::failbit);
getvalue(is, n);
std::cout << n << std::endl;
// Force Fail reading after EOF
getvalue(is, n);
std::cout << n << std::endl;
}
catch(std::ios::failure &fail)
{
std::cout << "Fail" << std::endl;
}
}
libstdc ++的输出:
123
456
789
Fail
libc ++ / libcxxrt输出:
123
456
789
0
还在OS X上进行了测试。
答案 0 :(得分:4)
libc ++正在回应27.7.2.1 [istream] / p4,它描述了basic_istream
的{{1}}解析operator>>
:
如果其中一个被调用的函数抛出异常,则除非 另外明确指出,输入函数设置错误的badbit 州。如果在exceptions()中打开了badbit,则输入函数会重新生成 没有完成其动作的异常,否则它不会 抛出任何东西并继续进行,好像被调用的函数已返回a 失败指示。
如果:
unsigned
然后获得所需的行为。
is.exceptions(std::ios::failbit | std::ios::badbit);
<强>更新强>
chico在下面的评论中正确地指出他希望123
456
789
Fail
投掷,而不是getline(is, s, ',')
提取器。
查看描述此unsigned
的21.4.8.9 [string.io] / p7:
效果:表现为无格式输入功能(27.7.2.3),除外 它不会影响后续调用返回的值 basic_istream&LT;&GT; :: gcount的()。构建一个岗哨对象后,如果 sentry转换为true,调用str.erase()然后提取 from中的字符并将它们附加到str,就好像通过调用一样 str.append(1,c)直到发生以下任何一种情况:...
所以问题就变成了:
未格式化的输入函数如何表现?
27.7.2.3 [istream.unformatted] / p1说:
每个未格式化的输入函数通过构造一个来开始执行 类哨兵的对象,默认参数为noskipws(第二个) 论证是真的。如果sentry对象返回true,则转换为a时 bool类型的值,该函数努力获得所请求的 输入。否则,如果哨兵构造函数通过抛出一个退出 异常或者如果sentry对象返回false,则转换为a时 bool类型的值,函数返回而不尝试获取 任何输入。在任何一种情况下,提取的字符数都设置为 0;未格式化的输入函数,其字符数组为非零 size作为参数也应该存储一个空字符(使用charT()) 在数组的第一个位置。 如果在此期间抛出异常 输入然后ios :: badbit在* this的错误状态下打开 315 。 (不会捕获从basic_ios&lt;&gt; :: clear()抛出的异常或 rethrown。)if(exceptions()&amp; badbit)!= 0则异常 rethrown。它还会计算提取的字符数。如果不 通过将计数存储在成员中来抛出异常 对象并返回指定的值。无论如何,哨兵 在离开未格式化的输入函数之前,对象被销毁。
315)这样做不会导致ios ::失败。
(为了便于阅读,我强调了)
所以这再次表明如果需要从此解析操作中获得异常,则必须在getline
中设置badbit
。