wake-up-neo.com

C++ 11 std :: to_string (double) - Keine nachgestellten Nullen

Heute habe ich einige neue Funktionen der C++ 11-STL ausprobiert und auf std::to_string gestoßen.

Schöne, schöne Reihe von Funktionen. Das Erstellen eines Stringstream-Objekts für nur eine Double-to-String-Konvertierung erschien mir immer übertrieben, daher bin ich froh, dass wir jetzt so etwas tun können:

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

Das Ergebnis?

0.330000

Damit bin ich nicht ganz zufrieden. Gibt es eine Möglichkeit, std::to_string anzuweisen, die nachgestellten Nullen wegzulassen? Ich habe im Internet gesucht, aber soweit ich sehen kann, benötigt die Funktion nur ein Argument (den umzuwandelnden Wert). In früheren Zeiten mit Stringstreams konnte man die Breite des Streams einstellen, aber ich möchte lieber nicht zurück konvertieren.

Hat jemand dieses Problem schon einmal festgestellt/hat eine Lösung? Einige StackOverflow-Suchen führten zu nichts.

(Eine C++ 11-AWL-Referenz: http://en.cppreference.com/w/cpp/string/basic_string/to_string )

48
Stijn Frishert

Der C++ 11-Standard sagt ausdrücklich (21.5/7):

Rückgabewert: Jede Funktion gibt ein Zeichenfolgenobjekt zurück, das die Zeichendarstellung des Werts seines Arguments enthält, das durch den Aufruf von sprintf (buf, fmt, val) mit einem Formatbezeichner von "% d", "% u", "% ld" generiert würde ","% lu ","% lld ","% llu ","% f ","% f "oder"% Lf ", wobei buf einen internen Zeichenpuffer ausreichender Größe bezeichnet

für die in dieser Reihenfolge deklarierten Funktionen:

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);

Daher können Sie die Formatierung der resultierenden Zeichenfolge nicht steuern.

31
rubenvb

Wenn Sie nur nachfolgende Nullen entfernen möchten, ist das ganz einfach.

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

std::to_string gibt Ihnen keine Kontrolle über das Format. Sie erhalten dasselbe Ergebnis wie sprintf mit dem entsprechenden Formatbezeichner für den Typ (in diesem Fall "%f").

Wenn Sie mehr Flexibilität benötigen, benötigen Sie einen flexibleren Formatierer - beispielsweise std::stringstream.

13
Mike Seymour

std::to_string(double) wird vom Standard definiert, um nur die gleiche Zeichenfolge zurückzugeben, die von sprintf(buf, "%f", value) generiert würde. Nicht mehr, nicht weniger, insbesondere keine Möglichkeit, den Formatbezeichner zu optimieren. Also nein, du kannst nichts tun.

3
Arne Mertz

Mit boost::to_string können Sie das Format auch nicht steuern, es wird jedoch etwas näher an das ausgegeben, was Sie auf dem Bildschirm sehen. Gleiches mit std::lexical_cast<std::string>.

Für eine funktionsähnliche Operation mit Formatsteuerung verwenden Sie str(boost::format("...format...")% 0.33).

Was ist der Unterschied zwischen std :: to_string, boost :: to_string und boost :: lexical_cast <std :: string>?

1
alfC

Erstellen Sie eine benutzerdefinierte Konvertierungsfunktion, und entfernen Sie ggf. die Nullstellen. 

//! 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;
}

Die eingabenummern: 

1230
12.30

Kompilieren Sie mit -std=c++11, dann das Ergebnis:

1230
12.3
0
Kinght 金

Eine abwechslungsreiche Lösung für das Problem, da to_string nicht funktioniert . "The Magic Formula" - mein CS2400-Lehrer

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;

Ausgänge: 

$0.33
$42.37

alle folgenden Ausgaben, die Sie mit Dezimalzahlen ausführen, werden entsprechend festgelegt.

sie können den Sollwert und die Präzision jederzeit ändern.

0
StackAttack