现在的位置: 首页 > 综合 > 正文

C++中数值–字符串间的转换

2013年12月13日 ⁄ 综合 ⁄ 共 2270字 ⁄ 字号 评论关闭
编写代码时经常需要在数值(int, long, float, double ...)与字符串间的相互转换。C/C++中相关的转换方法主要有如下几种:
    (一)、使用CRT库中的转换函数族。
  • _itoa, _itow 及其反转换 atoi, _wtoi
  • _ltoa, _ltow 及其反转换 atol, _wtol
  • _ultoa, _ultow
  • _ecvt, _fcvt, _gcvt 及其反转换
  • _atodbl, _atoldbl,_atoflt
  • ...(太多了,不想写了)

             使用此方法的优点:是C标准库中函数,现成可用且可移植(部分为平台相关)。
             缺点:转换函数较多,命名不统一以致难以记住,使用不方便。

    (二)、借助C++98标准中的stringstream模板类实现。

             数值到字符串的转换可如下实现:      

  1. template <typename CharT, typename NumericT>
  2. basic_string<CharT> Numeric2String(NumericT num)
  3. {
  4.      basic_ostringstream<CharT> oss;
  5.      oss << num;
  6.      return oss.str();
  7. }

    
其中,CharT类型可以是char或wchar_t,对应的返回类型分别是string和wstring。NumericT类型除了可以是int,
long, float等内建(build-in)数值类外型,还可以是重载了operator <<
运算符的class类型。像这样使用:     

  1. string str = Numeric2String<char>(10);
  2. wstring wstr = Numeric2String<wchar_t>(10.1f);

            同理,我们可以实现字符串到数值的转换:

  1. template <typename NumericT, typename CharT>
  2. NumericT String2Numeric(const basic_string<CharT> &str)
  3. {
  4.      basic_istringstream<CharT> iss(str);
  5.      NumericT result;
  6.      iss >> result;
  7.      return result;
  8. }

           为了支持C风格字符串直接到数值的转换,我们可以像这样为其重载一个转换:

  1. template <typename NumericT, typename CharT>
  2. NumericT String2Numeric(const CharT *str)
  3. {
  4.      basic_istringstream<CharT> iss(str);
  5.      NumericT result;
  6.      iss >> result;
  7.      return result;
  8. }

    细心的读者可能已经发现两个String2Numeric转换代码相同,为什么还要重载呢?这是因为我们要借助basic_istringstream类模板,需要得到CharT类型,假如我们这样:

  1. template <typename NumericT, typename StringT>
  2. NumericT String2Numeric(const StringT &str)
  3. {
  4.      basic_istringstream<??????> iss(str);
  5.      ...
  6. }

      那怎么生成basic_istringstream对象呢?若StringT是string或wstring,可以这样basic_istringstream<string::value_type>, 可还是不支持C字符串。

            此方法的优点:转换函数少,容易记住,使用方便。
            缺点:模板编程对于C++初学者来说有难度,需手工实现。

    (三)、使用第三方库。

           例如boost中的lexical_cast模板:

  1. string str = lexical_cast<string>(10);
  2. int i = lexical_cast<int>("20");

           早期的lexical_cast实现技术大致与(二)中的相似,借助string流、重载及模板机制。
           使用此种方法的优点:功能强大且稳定,仅有唯一的转换接口。
           缺点:需学习研究方能使用。

    (四)、使用sprintf、sscanf。

其函数原型为:

  1. int sprintf(char *buffer, const char *format [,argument] ...);
  2. int swprintf(wchar_t *buffer, size_t count, const wchar_t *format [, argument]...);
  3. int sscanf(const char *buffer, const char *format [,argument ] ...);
  4. int swscanf(const wchar_t *buffer, const wchar_t *format [,argument ] ...);

           此种方法的最大弊端是数组缓冲区容易益处,且无类型安全检查。强烈不推荐使用。

    (五)、其它未列出方法。

抱歉!评论已关闭.