使用boost::lexical_cast产生异常的问题
来源:优易学  2011-12-1 12:01:44   【优易学:中国教育考试门户网】   资料下载   IT书店

  一个关于使用boost::lexical_cast产生异常的问题,关键代码如下
  string str(8,'\0');
  strncpy(&str.at(0),"1234567",7);
  cout << lexical_cast<int>(str) << endl;
  结果运行的时候发生如下异常
  terminate called after throwing an instance of 'boost::bad_lexical_cast'
  what(): bad lexical cast: source type value could not be interpreted as target
  我们知道boost::lexical_cast最终使用的stringstream实现的数值类型转换,所以,我们使用如下例子,做测试
  stringstream ss;
  ss << str;
  ss >> result;
  cout << "new Result: " << result << endl;
  编译运行后,输出
  new Result: 1234567
  可以正常显示,好像没有问题,
  我们察看一下boost的源代码
  vim /usr/include/boost/lexical_cast.hpp
  察看lexical_cast函数
  template<typename Target, typename Source>
  Target lexical_cast(Source arg)
  {
  detail::lexical_stream<Target, Source> interpreter;
  Target result;
  if(!(interpreter << arg && interpreter >> result))
  throw_exception(bad_lexical_cast(typeid(Target), typeid(Source)));
  return result;
  }
  可见lexical_cast函数非常简单,就是具体执行operator<<和operator>>两个操作,只要这两个操作有一个失败就抛出一个异常,为了确认是那步出的错,我们在程序中手工执行这两个操作。代码如下
  detail::lexical_stream<int, string> interpreter;
  int result;
  if(!(interpreter << str ))
  {
  cout << "Error 1" << endl;
  }
  if(!(interpreter >> result))
  {
  cout << "Error 2" << endl;
  }
  cout << result << endl;
  编译运行后输出
  Error 2
  从这里我们知道,lexical_cast是在执行输出流的时候发生的问题,察看detail的operator>>函数,青年人网提示其源代码如下
  template<typename InputStreamable>
  bool operator>>(InputStreamable &output)
  {
  return !is_pointer<InputStreamable>::value &&
  stream >> output &&
  (stream >> std::ws).eof();
  }
  根据以上代码和我们使用stringstream做的测试,基本上可以确定在stream>>output(包括次步)都是正确的,可能出现问题的是(stream >> std::ws).eof();
  这里解释下std::ws和stringstring::eof()函数
  Std::ws函数声明在
  /usr/include/c++/3.4.4/bits/istream.tcc
  源代码如下
  // 27.6.1.4 Standard basic_istream manipulators
  template<typename _CharT, typename _Traits>
  basic_istream<_CharT,_Traits>&
  ws(basic_istream<_CharT,_Traits>& __in)
  {
  typedef basic_istream<_CharT, _Traits> __istream_type;
  typedef typename __istream_type::__streambuf_type __streambuf_type;
  typedef typename __istream_type::__ctype_type __ctype_type;
  typedef typename __istream_type::int_type __int_type;
  const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
  const __int_type __eof = _Traits::eof();
  __streambuf_type* __sb = __in.rdbuf();
  __int_type __c = __sb->sgetc();
  while (!_Traits::eq_int_type(__c, __eof)
  && __ct.is(ctype_base::space, _Traits::to_char_type(__c)))
  __c = __sb->snextc();
  if (_Traits::eq_int_type(__c, __eof))
  __in.setstate(ios_base::eofbit);
  return __in;
  }
  主要作用是过滤输入流中的空格,\n\r等字符。stream >> std::ws目的就是把输入流中转换完整形后的剩余流内容(假如有的话)写入std::ws,当然只能写入其中的空格和\n\r等字符。
  stringstring::eof()函数参考 http://www.cppreference.com/wiki/io/eof 部分
  该函数的主要作用是,如果到达流的结束位置返回true,否则返回false
  根据以上信息,我们编写测试用例
  stringstream ss;
  ss << str;
  ss >> result;
  cout << "new Result: " << result << endl;
  cout << ss.eof() << endl;
  cout << (ss >> std::ws).eof() << endl;

[1] [2] 下一页

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训