istream提取没有明显原因地设置failbit
std::istream extraction sets failbit for no apparent reason
我正在创建一个基本类型包装器,它可以使用boost::lexical_cast从字符串设置其值。它工作得很好,但是由于某种原因std::istream提取操作符设置了failbit。下面的程序打印:
123.45
EXCEPTION: ios_base::failbit set
但是如果你注释掉"stream . net"这行。异常(…"它工作并打印:
123.45
123.45
无论是否使用unicode进行编译,或者使用int或float作为ValueType, failbit在任何情况下都会被设置。
#include <conio.h>
#include <exception>
#include <iostream>
#include <string>
#include <tchar.h>
#include <boost/lexical_cast.hpp>
#if defined(UNICODE) || defined(_UNICODE)
typedef std::wstring StringType;
typedef std::wistream IStreamType;
#else
typedef std::string StringType;
typedef std::istream IStreamType;
#endif
#if 1 // Use float
typedef float ValueType;
#define VALUE_STRING _T("123.45")
#else // Use int
typedef int ValueType;
#define VALUE_STRING _T("123")
#endif
struct Castable {
ValueType m_val;
};
inline IStreamType& operator>> ( IStreamType& inStream, Castable& castable )
{
inStream.exceptions( IStreamType::failbit | IStreamType::badbit );
inStream >> castable.m_val;
return inStream;
}
int _tmain(int argc, _TCHAR* argv[])
{
try{
StringType sVal = VALUE_STRING;
ValueType val;
val = boost::lexical_cast<ValueType>(sVal);
std::cout << val << std::endl;
Castable cst;
cst = boost::lexical_cast<Castable>(sVal);
std::cout << cst.m_val << std::endl;
}catch( std::exception& ex ){
std::cout << "EXCEPTION: " << ex.what() << std::endl;
}
_getch();
return 0;
}
为什么std::istream会认为出错了?
这样做的一个原因可能是lexical_cast
的实现可能故意尝试导致某些流失败,以便检查所有输入文本是否已被消耗。例如,一个简单的实现可能是这样的:
template <typename Target>
Target lexical_cast(const string& s) {
/* Insert the string into a stringstream to use extraction. */
std::stringstream converter(s);
/* Pull out an object of type Target, failing if we can't. */
Target result;
if (!(converter >> result)) throw bad_lexical_cast();
/* To confirm that we read everything out of the stream, try pulling out a
* single character. If we can do this, then there is something left in the
* stream that wasn't picked up earlier and the input was malformed.
*/
char ch;
if (converter >> ch) throw bad_lexical_cast();
return result;
}
这里的想法是,最后的检查试图打破流,看看是否有东西被留下。如果你启用异常,这将把一些应该是正常的流故障检测到failbit
变成一个异常,这是代码没有预料到的。
一般来说,你不应该在提取例程中设置流设置。这取决于打电话的人。否则,无论您在调用提取例程之前尝试对流做什么,例程都会覆盖您的首选项。这将是糟糕的,毕竟,如果我显式禁用异常,然后有异常发生,因为你在operator >>
内部打开它们。
希望这对你有帮助!
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++/Linux中设置单调时钟的一些技巧
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 嵌套在类中时无法设置成员数据
- 需要帮助设置在C++中使用的Potrace
- 如何在自删除后将对象设置为nullptr
- 将指针设置为"nullptr"并不能防止双重删除?
- 如何在Ubuntu中使用cmake设置qt4
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 如何在boost beast http请求中设置http头
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 如何在24位SDL_Surface上设置像素的颜色
- 为什么即使输入有效,也总是设置 cin.failbit
- 使用getline()而不设置failbit
- istream提取没有明显原因地设置failbit
- Ifstream在读取文本文件时设置failbit
- 在c++中执行getline函数调用时,何时设置failbit ?
- 为什么设置了failbit()