C++數值--字符串間轉換方法總結

C++數值--字符串間轉換方法總結
                                ——林石 2008-09-17編程

編寫代碼時常常須要在數值(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模板:ui

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

           早期的lexical_cast實現技術大體與(二)中的類似,藉助string流、重載及模板機制。
           使用此種方法的優勢:功能強大且穩定,僅有惟一的轉換接口。
           缺點:需學習研究方能使用。

    (四)、使用sprintf、sscanf。spa

其函數原型爲:
  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 ] ...);

        試想一下當你寫出以下代碼時編譯器還呆頭呆腦地一如既往的幫你工做的情形吧:orm

  1. char buf[2];
  2. sprintf(buf, "%d", 1000); // ooh. Compile-Ok
  3. char buf2[20];
  4. sprintf(buf2, "%s", 1000); // ooh. Compile-Ok

            此種方法的最大弊端是數組緩衝區容易益處,且無類型安全檢查。強烈不推薦讀者使用。

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

相關文章
相關標籤/搜索