2009-06-17 25 views
7

一個常見的國際問題是在字符串中表示的雙值轉換。這些東西在很多地方都有。雙字符串轉換和區域設置

與要麼叫

comma separated 

character separated 

因爲有時它們存儲像

1.2,3.4 
5.6,6.4 
在英語地區

CSV文件啓動例如德國地區的

在這個背景下,需要知道大部分std ::方法都依賴於語言環境。所以在德國,他們將1.2讀爲1.2,並將其寫回爲「1,2」,但使用英文操作系統時,它會將「1,2」讀爲1並將其寫回爲「1」。

由於語言環境是應用程序的全局狀態,因此將其切換到不同的設置並不是一個好主意;當我必須在英文機器上閱讀德文CSV文件時,我們遇到了一些問題,反之亦然。

編寫在所有機器上表現相同的代碼也很困難。 C++流允許每個流的區域設置。

class Punctation : public numpunct<wchar_t> 
{ 
public: 

    typedef wchar_t char_type; 
    typedef std::wstring string_type; 

    explicit Punctation(const wchar_t& decimalPoint, std::size_t r = 0) : 
    decimalPoint_(decimalPoint), numpunct<wchar_t>(r) 
    { 
    } 

    Punctation(const Punctation& rhs) : 
    decimalPoint_(rhs.decimalPoint_) 
    { 
    } 

protected: 

    virtual ~Punctation() 
    { 
    }; 

    virtual wchar_t do_decimal_point() const 
    { 
    return decimalPoint_; 
    } 

private: 

    Punctation& operator=(const Punctation& rhs); 

    const wchar_t decimalPoint_; 
}; 

... 

std::locale newloc(std::locale::classic(), new Punctation(L',')); 
stream.imbue(newloc); 

將允許你用的std ::ç行爲初始化流,只有更換小數點。這使我能夠忽略可能會影響到的千位分隔符。 德國1000.12可能變成「1.000,12」;或英文「1,000.12」將完全混淆。即使用「」替換「,」。在這種情況下將無濟於事。

如果我有atof和朋友一起,我可以使用

const char decimal_point = *(localeconv()->decimal_point); 

皮條客我的行爲。

因此,只有國際雙重行爲纔有可怕的數量。即使我的Visual Studio也遇到了問題,因爲德語版本要將8,0作爲版本寫入vcproj文件,而英語版本則希望將其更改爲8.0,而這種情況通常是由事件發生的,因爲在XML中它被定義爲8.0世界各國。

所以我只是想描述一下這個問題,問一些我可能忽略的方面。 事情,我知道:

  • 小數品脫依賴於語言環境
  • 000分離依賴於語言環境
  • 指數是依賴於語言環境

//     German  English  Also known 
// decimal point  ,   .    
// exponent   e/E   e/E   d/D 
// thousand sep  .   , 

哪個國家使用哪種設置?也許你可以給我添加一些我迄今爲止沒有的有趣的例子。

+0

http://en.wikipedia.org/wiki/Decimal_point#Examples_of_use – Pod 2009-06-17 08:18:39

回答

2

永遠不要使用atof(s)。這是一個很快的& strtod(s,0)的髒快捷方式,沒有錯誤報告。 (同爲的atoi(),並與strtol()。)

如果一個函數被通告在困難的情況下返回錯誤代碼,你 必檢查該代碼,是啊,即使檢查三倍大小你的代碼 並在你的打字手指中產生疼痛,因爲如果你覺得'它不可能發生在我身上',那麼衆神必定會懲罰你的傲慢。

(亨利·斯賓塞, 「十誡爲C程序員」,誡#6)