2009-09-14 26 views
9

C++にはfloat/double変数があります。ダブルをカンマで印刷する方法

これをたとえばcoutと一緒に印刷すると、結果の文字列はピリオドで区切られます。

cout << 3.1415 << endl 
$> 3.1415 

ダブルをカンマで印刷する簡単な方法はありますか?

cout << 3.1415 << endl 
$> 3,1415 

答えて

11

imbue() coutで別のロケールをimbue()することができます。

このような入手は、いくつかの方法で行うことができます。システム上で利用可能な名前付きロケールを使用することができます(おそらくstd::locale("fr"))。あるいは、自分の数字を派生させて、do_decimal_point()のメンバーを実装することもできます。

第二のアプローチの例:として使用

template<typename CharT> 
class DecimalSeparator : public std::numpunct<CharT> 
{ 
public: 
    DecimalSeparator(CharT Separator) 
    : m_Separator(Separator) 
    {} 

protected: 
    CharT do_decimal_point()const 
    { 
     return m_Separator; 
    } 

private: 
    CharT m_Separator; 
}; 

std::cout.imbue(std::locale(std::cout.getloc(), new DecimalSeparator<char>(','))); 
+0

を使用すると、次の結果が得られます。std :: runtime error locale :: facet :: _ S_create_c_locale name not valid – NomeN

+0

このエラーは、ご使用のプラットフォームで "fr"という名前がロケールにバインドされていない可能性があります。 –

+0

私はそれほど推測しましたが、どの名前がロケールにバインドされているかを知ることができました。 – NomeN

2

これは、プログラムのロケールによって制御されます。

プログラムのデフォルトロケールの設定方法は、プラットフォームによって異なります。 POSIXタイプのプラットフォームでは、たとえばLANGおよびLC_ *環境変数を使用します。

ios :: imbueを呼び出すことによって、C++プログラム内で特定のロケール(デフォルトとは異なる)を強制することができます。このようなものがうまくいくかもしれません:

#include <locale> 
cout.imbue(std::locale("German_germany")); 

カンマが小数点の区切り文字であるロケールを強制することです。特定のプラットフォームで必要な動作を得るには、 "German_germany"文字列を調整する必要があります。

+0

例を使用すると、次の結果が得られます:ロケール:: facet :: _ S_create_c_localeの名前が無効 – NomeN

3

ストリームを異なるロケール(num_punct(iirc)ファセットがカンマを指定するロケール)で埋め込む必要があります。

カンマを使用して、プラットフォームのロケール形式ならば、

cout.imbue(locale("")); 

は十分なはずです。

+0

tあなたの答えはうまくいった。しかし、私はより一般的な答えを受け取りたいと思っています(プラットフォーム上の正しいロケールのプリセットで幸運でない場合)。一番簡単な方法なので+1してください。 – NomeN

1

正確には、これはstd::numpunct<charT>::decimal_point()値によって制御されます。あなたはlocalenumpunct面のdecimal_point()メンバ関数は、カンマを返すと、別のdecimal_point()

0

旧スレッド、とにかく...一つはstd::localeを使用して文字列が "かわいい" になることに注意する必要があり、プラットフォームとロケールによっては、正しい小数点、桁区切り記号、および区切り記号を使用してください。たぶん、imbue()を使用すると、書式設定された後の文字列の解析が壊れます。例えば:strtod()または2番目の文字列に類似したを使用して
without locale: 1234.56
with fr locale: 1 234,56

おそらく非常にうまく動作しません...また、1」の間にスペースを:

std::ostringstream s; 
std::locale l("fr-fr"); 
s << "without locale: " << 1234.56L << std::endl; 
s.imbue(l); 
s << "with fr locale: " << 1234.56L << std::endl; 
std::cout << s.str(); 

は、次の出力が与えます2番目の出力文字列の "2"は文字列をさらにきれいにします:-)

関連する問題