std :: lexical_cast - gibt es so etwas?


76

Definiert die C ++ - Standardbibliothek diese Funktion oder muss ich auf Boost zurückgreifen?

Ich suchte im Internet und konnte nichts außer Boost finden, aber ich dachte, ich sollte hier besser fragen.


6
Sie können auch auf Stringstreams "zurückgreifen" :)
Lightness Races in Orbit

Antworten:


90

Nur teilweise.

C ++ 11 <string>hat std::to_stringfür die eingebauten Typen:

[n3290: 21.5/7]:

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

Rückgabewert : Jede Funktion gibt einen stringGegenstand hält die Zeichendarstellung des Wertes seines Arguments , das durch den Aufruf erzeugt wird , würde sprintf(buf, fmt, val)mit einem Format - Spezifizierer aus "%d", "%u", "%ld", "%lu", "%lld", "%llu", "%f", "%f", oder "%Lf"jeweils gegebenen bufbezeichnet einen internen Zeichenpuffer mit ausreichender Größe.

Es gibt auch die folgenden, die umgekehrt sind:

[n3290: 21.5/1, 21.5/4]:

int stoi(const string& str, size_t *idx = 0, int base = 10);
long stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);
long long stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);
float stof(const string& str, size_t *idx = 0);
double stod(const string& str, size_t *idx = 0);
long double stold(const string& str, size_t *idx = 0);

Es gibt jedoch nichts Generisches, das Sie verwenden können (zumindest nicht bis TR2 , vielleicht!), Und überhaupt nichts in C ++ 03.


2
Hum, eigentlich gibt es stoiund Freunde :)
Matthieu M.

3
@mcheema: stroustrup.com/C++11FAQ.html#delegating-ctor dann. Entweder meint er Boost, oder er benutzt es als willkürliche Abstraktion, um einen Punkt zu machen, oder er liegt falsch.
Leichtigkeitsrennen im Orbit

2
@mcheema: Wir können alle daran interessiert sein, gute Codierungspraktiken zu verbreiten, aber das macht sie nicht weniger subjektiv!
Leichtigkeitsrennen im Orbit

3
@mcheema Ich erinnere mich an Stroustrups Sucht, fett kursiv proportionale Schrift für Code zu verwenden, und glaube nicht, dass man jemals ernsthaft über den Stil seines Codes sprechen kann. * Witz *
polkovnikov.ph

1
@LightnessRacesinOrbit Ich habe keine weiteren Gerüchte darüber gesehen, die es zu einer technischen Spezifikation gemacht haben. Ist es gestorben? TT
Jonathan Mee


11

Es gibt keinen std :: lexical_cast, aber mit stringstreams können Sie immer etwas Ähnliches tun :

template <typename T>
T lexical_cast(const std::string& str)
{
    T var;
    std::istringstream iss;
    iss.str(str);
    iss >> var;
    // deal with any error bits that may have been set on the stream
    return var;
}

3
danke aber das wäre noch langsamer als boost :: lexical_cast
smallB

4
Eine Stream-basierte Lösung wird nicht so schnell sein wie snprintf, aber Sie haben in Ihrer Frage keine Leistungsprobleme erwähnt.
Luke

12
Leistung ist immer ein Problem, aber es ist nie das einzige Problem. Einfachheit, Klarheit, Korrektheit und Wartbarkeit sind ebenfalls sehr wichtig. Ich würde den obigen Code nicht in einer engen Schleife verwenden, aber es könnte für andere Situationen in Ordnung sein. Eine häufig gestellte Frage in Bezug auf die Leistung auf SO, wenn Sie Ihren Code profiliert haben, und fanden heraus , dass das Opfer von anderen Anliegen lohnen :)
luke

8
Wenn Sie lexical_cast<string>(string)dies verwenden, wird nur das erste Wort zurückgegeben, nicht das, was Sie übergeben. (Sie können es in einer Vorlagenfunktion oder etwas anderem verwenden, nicht direkt.) Etwas, auf das Sie achten müssen.
Tmandry

2
Diese Version kann viel beschleunigt werden, indem issstatisch gemacht wird
MM


5

Wenn Sie keinen Boost möchten, implementiert eine Lightweight-Bibliothek namens fmt Folgendes:

// Works with all the C++11 features and AFAIK faster then boost or standard c++11
std::string string_num = fmt::format_int(123456789).str(); // or .c_str()

Weitere Beispiele von der offiziellen Seite .

Zugriff auf Argumente nach Position:

format("{0}, {1}, {2}", 'a', 'b', 'c');
// Result: "a, b, c"
format("{}, {}, {}", 'a', 'b', 'c');
// Result: "a, b, c"
format("{2}, {1}, {0}", 'a', 'b', 'c');
// Result: "c, b, a"
format("{0}{1}{0}", "abra", "cad");  // arguments' indices can be repeated
// Result: "abracadabra"

Text ausrichten und Breite angeben:

format("{:<30}", "left aligned");
// Result: "left aligned                  "
format("{:>30}", "right aligned");
// Result: "                 right aligned"
format("{:^30}", "centered");
// Result: "           centered           "
format("{:*^30}", "centered");  // use '*' as a fill char
// Result: "***********centered***********"

Ersetzen von% + f,% -f und% f und Angeben eines Vorzeichens:

format("{:+f}; {:+f}", 3.14, -3.14);  // show it always
// Result: "+3.140000; -3.140000"
format("{: f}; {: f}", 3.14, -3.14);  // show a space for positive numbers
// Result: " 3.140000; -3.140000"
format("{:-f}; {:-f}", 3.14, -3.14);  // show only the minus -- same as '{:f}; {:f}'
// Result: "3.140000; -3.140000"

Ersetzen von% x und% o und Konvertieren des Werts in verschiedene Basen:

format("int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
// Result: "int: 42;  hex: 2a;  oct: 52; bin: 101010"
// with 0x or 0 or 0b as prefix:
format("int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}", 42);
// Result: "int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010"

Ich mag die fmtBibliothek sehr und möchte, dass ihre Nutzung gefördert wird. fmtDie Konvertierung in Zeichenfolgen wird jedoch nur durchgeführt . (Jetzt ist es das besser als jede andere C ++ Bibliothek , die ich gesehen habe.) fmtNicht tun , die aus String Konvertierung durchgeführt durch lexical_cast oder std :: stoxyz Funktionen.
Phil
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.