• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            對字符串類型和數(shù)值類型間進(jìn)行轉(zhuǎn)換問題的處理之Boost組件lexical_cast

            在CSDN論壇上經(jīng)常看到詢問如何在字符串類型和數(shù)值類型間進(jìn)行轉(zhuǎn)換的問題,也看到了許多不同的答案。下面先討論一下從字符串類型到數(shù)值類型的轉(zhuǎn)換。

            1. 如何將字符串"123"轉(zhuǎn)換為int類型整數(shù)123?答案是,用標(biāo)準(zhǔn)C的庫函數(shù)atoi;
            2. 如果要轉(zhuǎn)換為long類型呢?標(biāo)準(zhǔn)C的庫函數(shù)atol;
            3. 如何將"123.12"轉(zhuǎn)換為double類型呢?標(biāo)準(zhǔn)C的庫函數(shù)atod;
            4. 如果要轉(zhuǎn)換為long double類型呢?標(biāo)準(zhǔn)C的庫函數(shù)atold;
            5. ……

            后來有朋友開始使用標(biāo)準(zhǔn)庫中的string類,問這個(gè)如何轉(zhuǎn)換為數(shù)值?有朋友答曰,請先轉(zhuǎn)換為const char*。我很佩服作答者有數(shù)學(xué)家的思維:把陌生的問題轉(zhuǎn)化成熟悉的問題。(曾經(jīng)有一則笑話,好事者問數(shù)學(xué)家:知道如何燒水嗎?答:知道。把水壺加滿水,點(diǎn)火燒。又問:如果水壺里已經(jīng)有水了呢?答:先倒掉,就轉(zhuǎn)化為我熟悉的問題了……)

            不,不,這樣是C的做法,不是C++。那么,C++該怎么做呢?使用Boost Conversion Library所提供的函數(shù)lexical_cast(需要引入頭文件boost/lexical_cast.hpp)無疑是最簡單方便的。如:

            #include <boost/lexical_cast.hpp>
            #include <iostream>
            int main()
            {
                    using boost::lexical_cast;
                    int a = lexical_cast<int>("123");
                    double b = lexical_cast<double>("123.12");
                    std::cout<<a<<std::endl
                    std::cout<<b<<std::endl;
                    return 0;
            }

            一個(gè)函數(shù)就簡潔地解決了所有的問題。

            3.2 數(shù)值→字符串

            那么從數(shù)值類型到字符串類型呢?

            用itoa?不對吧,標(biāo)準(zhǔn)C/C++里根本沒有這個(gè)函數(shù)。即使在Windows平臺下某些編譯器提供了該函數(shù)3,沒有任何移植性不說,還只能解決int類型(也許其他函數(shù)還可以解決long、unsigned long等類型),浮點(diǎn)類型又怎么辦?當(dāng)然,辦法還是有,那就是:sprintf。

            char s[100];
            sprintf(s, "%f", 123.123456);

            不知道諸位對C里的scanf/printf系列印象如何,總之阿炯我肯定記不住那些稀奇古怪的參數(shù),而且如果寫錯(cuò)了參數(shù),就會得到莫名其妙的輸出結(jié)果,調(diào)試起來可就要命了(我更討厭的是字符數(shù)組,空間開100呢,又怕太小裝不下;開100000呢,總覺得太浪費(fèi),心里憋氣,好在C++標(biāo)準(zhǔn)為我們提供了string這樣的字符串類)。這時(shí)候,lexical_cast就出來幫忙啦。

            #include <boost/lexical_cast.hpp>
            #include <string>
            #include <iostream>
            int main()
            {
                    using std::string;
                    const double d = 123.12;
                    string s = boost::lexical_cast<string>(d);
                    std::cout<<s<<std::endl;
                    return 0;
            }

            跟前面一樣簡單。

            3.3 異常

            如果轉(zhuǎn)換失敗,則會有異常bad_lexical_cast拋出。該異常類是標(biāo)準(zhǔn)異常類bad_cast的子類。

            #include <boost/lexical_cast.hpp>
            #include <iostream>
            int main()
            {
                    using std::cout;
                    using std::endl;
                    int i;
                    try{
                            i = boost::lexical_cast<int>("abcd");
                    }
                    catch(boost::bad_lexical_cast& e)
                    {
                            cout<<e.what()<<endl;
                            return 1;
                    }
                    cout<<i<<endl;
                    return 0;
            }

            顯然“abcd”并不能轉(zhuǎn)換為一個(gè)int類型的數(shù)值,于是拋出異常,捕捉后輸出“bad lexical cast: source type value could not be interpreted as target”這樣的信息。

            3.4 注意事項(xiàng)

            lexical_cast依賴于字符流std::stringstream(會自動引入頭文件4),其原理相當(dāng)簡單:把源類型讀入到字符流中,再寫到目標(biāo)類型中,就大功告成。例如

            int d = boost::lexical_cast<int>("123");

            就相當(dāng)于

            int d;
            std::stringstream s;
            s<<"123";
            s>>d;

            既然是使用了字符流,當(dāng)然就有些隨之而來的問題,需要特別指出5

            • 由于Visual C++ 6的本地化(locale)部分實(shí)現(xiàn)有問題,因此如果使用了非默認(rèn)的locale,可能會莫名其妙地拋出異常。當(dāng)然,一般情況下我們并不需要去改變默認(rèn)的locale,所以問題不是很大。
            • 輸入數(shù)據(jù)必須“完整”地轉(zhuǎn)換,否則拋出bad_lexical_cast異常。例如
            int i = boost::lexical_cast<int>("123.123"); // this will throw 

            便會拋出異常。因?yàn)椤?23.123”只能“部分”地轉(zhuǎn)換為123,不能“完整”地轉(zhuǎn)換為123.123。

            • 浮點(diǎn)數(shù)的精度問題。
            std::string s = boost::lexical_cast<std::string>(123.1234567);

            以上語句預(yù)想的結(jié)果是得到“123.1234567”,但是實(shí)際上我們只會得到“123.123”,因?yàn)槟J(rèn)情況下std::stringstream的精度是6(這是C語言程序庫中的“前輩”printf留下的傳統(tǒng))。這可以說是boost::lexical_cast的一個(gè)bug。怎么辦呢?權(quán)宜之計(jì),可以這么做:打開頭文件<boost/lexical_cast.hpp>,注意對照修改6

            #include <boost/limits.hpp>
            //...
            template<typename Target, typename Source>
            Target lexical_cast(Source arg) {
                    //...
                    Target result; 
                    interpreter.precision(std::numeric_limits<Source>::digits10);
                    if( !(interpreter << arg) ||
                    !(interpreter >> result) ||
                    !(interpreter >> std::ws).eof())
                    //...
            }

            即可得到正確結(jié)果。當(dāng)然,理論上效率會有一點(diǎn)點(diǎn)損失,不過幾乎可以忽略不計(jì)。

            4 小結(jié)

            我們已經(jīng)體驗(yàn)了boost::lexcial_cast。當(dāng)然,lexical_cast不僅僅局限于字符串類型與數(shù)值類型之間的轉(zhuǎn)換:可在任意可輸出到stringstream的類型和任意可從stringstream輸入的類型間轉(zhuǎn)換。這次的了解盡管很粗略,不過畢竟我們已經(jīng)“走進(jìn)Boost”,而不僅僅是“走近”。以后,我們可以自行領(lǐng)略Boost的動人之處啦。

            posted on 2008-04-25 17:08 肥仔 閱讀(644) 評論(0)  編輯 收藏 引用 所屬分類: Boost & STL

            久久久国产乱子伦精品作者| 精品无码久久久久久国产| 国内精品久久久久伊人av| 久久国产精品-国产精品| 久久精品国产男包| 99久久久精品| 久久91精品国产91| 久久午夜电影网| 亚洲国产另类久久久精品| 久久精品不卡| 久久婷婷五月综合97色一本一本| 久久精品国产只有精品66| 99精品久久精品| 亚洲国产精品无码久久青草| 久久久久国产精品嫩草影院| 久久免费精品视频| 久久久久久久久久久久久久| 女同久久| 国产精品久久久天天影视香蕉| 97久久超碰国产精品2021| 久久综合给久久狠狠97色| 7777精品久久久大香线蕉| 亚洲欧洲久久av| 久久久亚洲精品蜜桃臀| 三级片免费观看久久| 九九热久久免费视频| 精品视频久久久久| 久久久精品一区二区三区| 日韩一区二区久久久久久| 亚洲天堂久久精品| 久久精品国产亚洲AV高清热| 777米奇久久最新地址| 久久精品免费一区二区三区| 国产精品嫩草影院久久| 久久影院午夜理论片无码| 亚洲国产精品无码久久青草 | 国产精品热久久毛片| 久久久无码精品亚洲日韩软件| 久久综合久久鬼色| 久久精品夜色噜噜亚洲A∨| 要久久爱在线免费观看|