【C++】字符串和數值類型的相互轉化(藉助STL)


寫在文章開頭的話

讀完這篇文章後,你將學到下面的知識:
(1)如何利用標準庫中的 std::stringstream 來完成字符串和數值類型的相互轉換
(2)如何利用 C++11 提供的字符串轉換函數,將std::string類型轉換爲數值類型

     在C++編程中有時會遇到字符串和數字的相互轉化,以前學習的時候老師喜歡將這種轉化當成作業,要我們寫函數實現。但是實際爲了方便準確還是會優先使用STL來完成。
     在 C 標準庫中提供了字符串到數值類型的轉化函數,但是沒有提供數值到字符串的轉換(不過有些系統如 Windows API中提供數值到字符串的轉化)。先看看C標準庫中的字符串轉化函數,這些函數都包含在頭文件 <cstdlib>中:

表1  C 標準庫中的字符串轉換函數

這些函數的用法想必都比較熟悉就不多說了,細節可以參考 C或C++ 標準庫。這裏主要說下藉助 C++ 標準模板庫中的 std::stringstream 來完成字符串的轉換, 以及 C++11新增的 std::string 轉換函數。

平時我們在用 std::cout 和 std::cin 時,感覺很直接,它能根據你的數據類型自動的執行輸入輸出操作,無論是字符、整型、浮點型,它都能以字符串形式輸出到控制檯,同樣也可以從控制檯讀入字符串,解析成各種數值類型。上面提到的 stringstream 派生自 iostream,繼承了iostream的輸入輸出操作,你可以把它看成std::cout 和 std::cin的內存版本,對其進行的輸入輸出不是與控制檯交互,而是與stringstream內部的字符串交互。下面是stringstream 的繼承圖:

圖1  C++標準I/O庫繼承圖

接下來舉兩個例子來說明如何使用stringstream來進行字符串和數值類型的相互轉化:

(1)字符串 --> 數值類型
     先準備好包含數值類型的字符串,然後定義 istringstream 實例,使用其輸入操作將其內部的字符串解析爲相應的數值類型,最後輸出。
#include <iostream>
#include <sstream>

int main()
{
    string str = "12 3.14";
    istringstream in(str);
    int v1;
    double v2;
    in >> v1 >> v2;
    cout << "v1=" << v1 << " ,v2=" << v2 << endl;
    return 0;
}

運行結果:
v1=12 ,v2=3.14

(2)數值類型 --> 字符串
     先準備好數值類型數據,然後定義 ostringstream 實例,使用其輸出操作將數值類型輸出到 stringstream 內部字符緩衝區中,最後調用 ostringstream::str() 成員函數獲取內部字符串。
#include <iostream>
#include <sstream>

int main()
{
    int v1 = 12;
    float v2 = 2.14f;
    double v3 = 3.1415926;
    long long v4 = 0x0123456789ABCDEF;
    ostringstream out;
    out << v1 << " "
        << v2 << " "
        << v3 << " "
        << hex << uppercase << v4;
    cout << "str=" << out.str() << endl;
    return 0;
}

運行結果:
 str=12 2.14 3.14159 123456789ABCDEF

如果不知道輸入輸出方向,也可以直接使用 stringstream。
 
由於 stringstream 沒有重載字節類型的轉換,可以通過限制寬度達到轉換字節的目的,例如下面:

unsigned char b = 0xAB;
std::ostringstream out;
out.width(2);
out << std::hex << std::uppercase << static_cast<unsigned short>(b);
先將單字節類型變量 b 轉化爲無符號整型,這樣可以被 stringstream 輸出從操作識別,同時限制輸出的寬度爲2位,截斷爲一個字節大小。
注意:out.width(int);僅對接下來的一次輸出有效,之後再輸出恢復默認寬度。

藉助std::string 的轉換函數

     C++11 中提供了 std::string 的幾個字符串轉換函數,可以方便的在字符串和數值類型間相互轉換。

圖 2  C++11 新增 std::string 轉換函數
   
 這是很方便的,但是各編譯器廠商支持尚不完全。 下面是測試的結果:
#include <string>
#include <iostream>
using namespace std;

int main()
{
     string s1 = "1234";
     string s2 = "3.14";
     int v1 = std::stoi(s1);
     float v2 = std::stof(s2);
     cout << v1 << " " << v2 << endl;
     string s3 = std::to_string(static_cast<long double>(v2)) + "15926";
     cout << s3 << endl;
     return 0;
}
運行結果:
1234 3.14
3.1415926

結論:
(1)gcc 4.8.1 尚不支持上面用法。
(2)VC++2010 支持 stox 的系列用法,但 to_string 只支持 long long / unsinged long long / long double 類型的轉換。
所以在使用上面轉換函數先看看編譯器是否支持,如不支持還是選擇使用 stringstream 或者 cstdlib 中提供的 C 函數進行字符串轉換。

發佈了50 篇原創文章 · 獲贊 27 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章