web-dev-qa-db-ja.com

C ++ 11 std :: to_string(double)-後続ゼロなし

今日、C++ 11 STLのいくつかの新しい機能を試してみたところ、std::to_stringに遭遇しました。

素敵で素敵な機能セット。 1回のdouble-to-string変換のためだけにstringstreamオブジェクトを作成することは、私にとって常にやり過ぎだと思われたので、次のようなことができるようになったことをうれしく思います。

std::cout << std::to_string(0.33) << std::endl;

結果?

0.330000

私はそれに満足しているわけではありません。 std::to_stringに末尾のゼロを省くように指示する方法はありますか?私はインターネットを検索しましたが、私が見ることができる限り、関数はたった1つの引数(変換される値)を取ります。文字列ストリームを使用して「昔」に戻ると、ストリームの幅を設定できますが、私は逆変換しないでください。

誰もこの問題に遭遇した/解決策を持っていますか?一部のStackOverflow検索では何も生成されませんでした。

(C++ 11 STLリファレンス: http://en.cppreference.com/w/cpp/string/basic_string/to_string

56
Stijn Frishert

C++ 11標準では、明示的に(21.5/7):

戻り値:各関数は、 "%d"、 "%u"、 "%ldの形式指定子を使用してsprintf(buf、fmt、val)を呼び出すことにより生成される引数の値の文字表現を保持する文字列オブジェクトを返します。 "、"%lu "、"%lld "、"%llu "、"%f "、"%f "、または"%Lf "。それぞれ、bufは十分なサイズの内部文字バッファーを示します。

この順序で宣言された関数の場合:

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);

したがって、結果の文字列のフォーマットを制御することはできません。

38
rubenvb

末尾のゼロを削除するだけなら、それは簡単です。

std::string str = std::to_string (f);
str.erase ( str.find_last_not_of('0') + 1, std::string::npos );
39
Marshall Clow

std::to_stringでは、形式を制御できません。タイプに適した形式指定子(この場合は"%f")を使用すると、sprintfと同じ結果が得られます。

より柔軟性が必要な場合は、std::stringstreamなどのより柔軟なフォーマッタが必要になります。

15
Mike Seymour

std::to_string(double)は、sprintf(buf, "%f", value)によって生成されるのと同じ文字シーケンスを返すように標準で定義されています。これ以上、それ以下、特にフォーマット指定子を微調整する方法はありません。だから、あなたにできることは何もない。

4
Arne Mertz

_boost::to_string_を使用すると、フォーマットを制御することもできませんが、画面に表示されるものに近いものを出力します。 _std::lexical_cast<std::string>_と同じです。

書式制御を使用した関数のような操作の場合は、str(boost::format("...format...")% 0.33)を使用します。

std :: to_string、boost :: to_string、およびboost :: lexical_cast <std :: string>?の違いは何ですか?

2
alfC

カスタム変換関数を作成し、必要に応じて末尾のゼロを削除します。

//! 2018.05.14 13:19:20 CST
#include <string>
#include <sstream>
#include <iostream>
using namespace std;

//! Create a custom convert function, remove the tailing zeros if necessary.  
template<typename T>
std::string tostring(const T &n) {
    std::ostringstream oss;
    oss << n;
    string s =  oss.str();
    int dotpos = s.find_first_of('.');
    if(dotpos!=std::string::npos){
        int ipos = s.size()-1;
        while(s[ipos]=='0' && ipos>dotpos){
            --ipos;
        }
        s.erase ( ipos + 1, std::string::npos );
    }
    return s;
}

int main(){
    std::cout<< tostring(1230)<<endl;
    std::cout<< tostring(12.30)<<endl;
}

入力番号:

1230
12.30

-std=c++11でコンパイルし、結果を次のようにします。

1230
12.3
1
Kinght 金

to_stringが機能しないため、さまざまな問題の解決策があります。 「マジックフォーミュラ」-CS2400の先生

std::cout.setf(ios::fixed);
std::cout.setf(ios::showpoint);
std::cout.precision(2);

const double x = 0.33, y = 42.3748;
std::cout << "$" << x << std::endl;
std::cout << "$" << y << std::endl;

出力:

$0.33
$42.37

10進数で行う次の出力は、そのように設定されます。

必要に応じてsetfと精度をいつでも変更できます。

0
StackAttack