Was ist der einfachste Weg, um in C ++ von int
einem Äquivalent zu konvertieren? string
Mir sind zwei Methoden bekannt. Gibt es einen einfacheren Weg?
(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
c++
string
int
type-conversion
Nemo
quelle
quelle
itoa()
drei Parameter erforderlich.Antworten:
C ++ 11 führt
std::stoi
(und Varianten für jeden numerischen Typ) undstd::to_string
die Gegenstücke des C einatoi
und wirditoa
jedoch in Term ausgedrücktstd::string
.ist daher der kürzeste Weg, den ich mir vorstellen kann. Sie können sogar die Benennung des Typs mit dem
auto
Schlüsselwort weglassen :Hinweis: siehe [string.conversions] ( 21,5 in n3242 )
quelle
to_string
kein Mitglied vonstd
fix: stackoverflow.com/questions/12975341/…g++ -std=c++11 someFile.cc
std
in jedem Compiler, den ich kenne, bis auf einen.Error : No instance of overloaded function "std::to_string" matches the argument list
erhalte diesen Fehler: Ich verwende VS2010 c ++string s = to_string((_ULonglong)i);
C ++ 17 hat einige Jahre später eine Diskussion mit @ v.oddou aufgenommen und bietet nun endlich die Möglichkeit, die ursprünglich makrobasierte typunabhängige Lösung ( siehe unten) zu erstellen, ohne die Makro-Hässlichkeit zu durchlaufen.
Verwendungszweck:
Ursprüngliche Antwort:
Da "Konvertieren ... in Zeichenfolge" ein wiederkehrendes Problem ist, definiere ich das Makro SSTR () immer in einem zentralen Header meiner C ++ - Quellen:
Die Verwendung ist so einfach wie möglich:
Das oben genannte ist C ++ 98-kompatibel (wenn Sie C ++ 11 nicht verwenden können
std::to_string
) und benötigt keine Includes von Drittanbietern (wenn Sie Boost nicht verwenden könnenlexical_cast<>
). Diese beiden anderen Lösungen weisen jedoch eine bessere Leistung auf.quelle
dynamic_cast
aber ich benutze Clang zum Kompilieren, damit es sich darüber beschwert. Wenn ich das einfach weglasse,dynamic_cast
wird es gut kompiliert; Welchen Zweck hat dasdynamic_cast
in diesem Fall? Wir erstellen bereits eineostringstream
, warum also besetzen?ostringstream
, riefen wiroperator<<()
darauf, die Erträgeostream &
- für die.str()
nicht definiert ist. Ich frage mich wirklich, wie Clang diese Arbeit ohne die Besetzung machen würde (oder warum es einen Fehler damit erzeugt). Dieses Konstrukt wird an vielen Stellen veröffentlicht, und ich habe es über ein Jahrzehnt lang auf vielen verschiedenen Compilern verwendet, einschließlich MSVC, GCC und XLC.do { } while( 0 )
würde nichts hinzufügen. Mit 2. und 3. haben Sie wahrscheinlich einen Punkt bekommen - dies könnte mit einer statischen Besetzung geschehen, und vielleicht könnte einer von Ihnen Vorlagenassistenten da draußen eine "schönere" Oberfläche finden. Aber wie gesagt, das ist keineswegs eine Erfindung von mir. Schauen Sie sich um, dieses Makro (Makro!) Ist ziemlich allgegenwärtig. Das ist ein Fall von POLA an sich. Ich könnte ein bisschen damit spielen, um es "schlanker" zu machen.Normalerweise verwende ich die folgende Methode:
Es wird im Detail beschrieben hier .
quelle
ss
müssen Siess.clear()
es. Ich habe unerwartete Ergebnisse ohne diese Initialisierung gesehen.clear()
neu erstelltesostringstream
Objekt erstellen .clear()
Setzt die Fehler- / Eof-Flags zurück und es wurde noch keine Fehler- / Eof-Bedingung generiert.NumberToString(23213.123)
produziert23213.1
währendstd::to_string(23213.123)
produziert23213.123000
Was passiert dort?Die wohl häufigste einfache Art und Weise wickelt im Wesentlichen Ihre zweite Wahl in eine Vorlage mit dem Namen
lexical_cast
, wie die in - Boost , so dass Ihr Code sieht wie folgt aus :Eine Besonderheit davon ist, dass es auch andere Casts unterstützt (z. B. funktioniert die entgegengesetzte Richtung genauso gut).
Beachten Sie auch, dass Boost lexical_cast zwar zunächst nur in einen Stringstream schrieb und dann wieder aus dem Stream extrahierte, jetzt aber einige Ergänzungen enthält. Zunächst wurden Spezialisierungen für einige Typen hinzugefügt, sodass diese für viele gängige Typen wesentlich schneller sind als die Verwendung eines Stringstreams. Zweitens wird jetzt das Ergebnis überprüft. Wenn Sie also beispielsweise von einer Zeichenfolge in eine konvertieren
int
, kann eine Ausnahme ausgelöst werden, wenn die Zeichenfolge etwas enthält, das nicht in eine konvertiert werden konnteint
(z. B.1234
wäre erfolgreich,123abc
würde aber werfen). .Ab C ++ 11 ist eine
std::to_string
Funktion für Ganzzahltypen überladen, sodass Sie Code wie folgt verwenden können:Der Standard definiert diese als äquivalent zur Konvertierung mit
sprintf
(unter Verwendung des Konvertierungsspezifizierers, der dem angegebenen Objekttyp entspricht, z. B.%d
fürint
) in einen Puffer mit ausreichender Größe und anschließendem Erstellen einesstd::string
Inhalts dieses Puffers.quelle
Wenn Sie Boost installiert haben (was Sie sollten):
quelle
Es wäre einfacher, Stringstreams zu verwenden:
Oder machen Sie eine Funktion:
quelle
Nicht das ich wüsste, in reinem C ++. Aber eine kleine Modifikation von dem, was Sie erwähnt haben
sollte funktionieren, und es ist ziemlich kurz.
quelle
itoa()
ist keine Standardfunktion!Sie können
std::to_string
verfügbar in C ++ 11 verwenden, wie von Matthieu M vorgeschlagen :Wenn die Leistung kritisch ist (z. B. wenn Sie viele Konvertierungen durchführen), können Sie
fmt::format_int
aus der {fmt} -Bibliothek eine Ganzzahl konvertieren instd::string
:Oder eine C-Zeichenfolge:
Letzterer führt keine dynamischen Speicherzuweisungen durch und ist mehr als zehnmal schneller als
std::to_string
bei Boost Karma-Benchmarks. Weitere Informationen finden Sie unter Schnelle Konvertierung von Ganzzahlen in Zeichenfolgen in C ++ .Beachten Sie, dass beide threadsicher sind.
Im Gegensatz zu
std::to_string
,fmt::format_int
erfordert nicht C ++ 11 und funktioniert mit jedem C ++ Compiler.Haftungsausschluss: Ich bin der Autor der {fmt} -Bibliothek.
quelle
c_str()
gibt einen Zeiger auf einen in derfmt::FormatInt
Klasse deklarierten Puffer zurück - damit der zurückgegebene Zeiger bei ungültig wird das Semikolon - siehe auch stackoverflow.com/questions/4214153/lifetime-of-temporariesstd::string::c_str()
(also die Benennung). Wenn Sie es außerhalb des vollständigen Ausdrucks verwenden möchten, erstellen Sie ein Objekt.FormatInt f(42);
Sie können es dann verwenden,f.c_str()
ohne dass die Gefahr besteht, dass es zerstört wird.sprintf()
ist ziemlich gut für die Formatkonvertierung. Sie können dann die resultierende C-Zeichenfolge der C ++ - Zeichenfolge wie in 1 zuweisen.quelle
NULL
Größe von Null auf, um die erforderliche Puffergröße zu erhalten.snprintf
(beachten Sie das SNP- Präfix) undsprintf
(beachten Sie das SP- Präfix). Sie übergeben die Größe an die erstere, und es wird darauf geachtet, dass sie nicht überläuft. Letztere kennt jedoch die Größe des Puffers nicht und kann daher überlaufen.snprintf
Variante und danach einesprintf
Variante aufzurufen . Da die Puffergröße bis dahin bekannt ist,sprintf
wird das Aufrufen völlig sicher.Zuerst umfassen:
Zweitens fügen Sie die Methode hinzu:
Verwenden Sie die Methode wie folgt:
oder
quelle
Die Verwendung von Stringstream zur Nummernkonvertierung ist gefährlich!
Siehe http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/, wo angegeben wird, dass
operator<<
formatierte Ausgaben eingefügt werden.Abhängig von Ihrem aktuellen Gebietsschema kann eine Ganzzahl mit mehr als 3 Ziffern in eine Zeichenfolge mit 4 Ziffern konvertiert werden, wobei ein zusätzliches Tausendertrennzeichen hinzugefügt wird.
Könnte
int = 1000
beispielsweise in einen String konvertiert werden1.001
. Dies könnte dazu führen, dass Vergleichsoperationen überhaupt nicht funktionieren.Daher würde ich die Verwendung des
std::to_string
Weges dringend empfehlen . Es ist einfacher und macht das, was Sie erwarten.Aktualisiert (siehe Kommentare unten) :
quelle
std::to_string
Verwendet leider auch das aktuelle Gebietsschema (siehe en.cppreference.com/w/cpp/string/basic_string/to_string , Abschnitt 'Notizen'). Fast alle Standardtools (von Stringstreams bissprintf
aber auchsscanf
usw.) verwenden das aktuelle Gebietsschema. Ich war mir dessen erst vor kurzem bewusst, als es mich hart traf. Derzeit werden einheimische Produkte verwendet, die nicht schwer herzustellen sind.Für C ++ 98 gibt es einige Optionen:
boost/lexical_cast
Boost ist kein Teil der C ++ - Bibliothek, enthält jedoch viele nützliche Bibliothekserweiterungen.
Was die Laufzeit betrifft,
lexical_cast
dauert der Vorgang bei der ersten Konvertierung etwa 80 Mikrosekunden (auf meinem Computer) und wird anschließend erheblich beschleunigt, wenn er redundant ausgeführt wird.itoa
Dies bedeutet, dass
gcc
/g++
Code nicht mit kompiliert werden kannitoa
.Keine Laufzeit zu melden. Ich habe Visual Studio nicht installiert, das Berichten zufolge kompiliert werden kann
itoa
.sprintf
sprintf
ist eine C-Standardbibliotheksfunktion, die mit C-Strings funktioniert und eine absolut gültige Alternative darstellt.Der
stdio.h
Header ist möglicherweise nicht erforderlich. Was die Laufzeit betrifft,sprintf
dauert der Vorgang bei der ersten Konvertierung etwa 40 Mikrosekunden (auf meinem Computer) und wird anschließend erheblich beschleunigt, wenn er redundant ausgeführt wird.stringstream
Dies ist die Hauptmethode der C ++ - Bibliothek zum Konvertieren von Ganzzahlen in Zeichenfolgen und umgekehrt. Es gibt ähnliche Schwesterfunktionen
stringstream
, die die beabsichtigte Verwendung des Streams weiter einschränken, wie zostringstream
. Die Verwendungostringstream
teilt dem Leser Ihres Codes ausdrücklich mit, dass Sie im<<
Wesentlichen nur den Operator verwenden möchten. Diese Funktion ist alles, was besonders notwendig ist, um eine Ganzzahl in eine Zeichenfolge umzuwandeln. In dieser Frage finden Sie eine ausführlichere Diskussion.Was die Laufzeit betrifft,
ostringstream
dauert der Vorgang ungefähr 71 Mikrosekunden (auf meinem Computer) und beschleunigt sich danach erheblich, wenn er redundant ausgeführt wird, jedoch nicht so stark wie die vorherigen Funktionen .Natürlich gibt es auch andere Optionen, und Sie können sogar eine davon in Ihre eigene Funktion einbinden, aber dies bietet einen analytischen Blick auf einige der beliebtesten.
quelle
C ++ 17 bietet std :: to_chars als leistungsstärkere, vom Gebietsschema unabhängige Alternative.
quelle
Es ist ziemlich einfach, etwas syntaktischen Zucker hinzuzufügen, der es einem ermöglicht, Strings im laufenden Betrieb stromartig zu komponieren
Jetzt können Sie anhängen, was Sie möchten (vorausgesetzt, ein Operator
<< (std::ostream& ..)
ist dafür definiert),strmake()
und es anstelle von verwendenstd::string
.Beispiel:
quelle
BEARBEITET. Wenn Sie eine schnelle Konvertierung einer Ganzzahl mit einer festen Anzahl von Ziffern in ein mit * 0 links aufgefülltes Zeichen * benötigen , ist dies das Beispiel für Little-Endian-Architekturen (alle x86, x86_64 und andere):
Wenn Sie eine zweistellige Zahl konvertieren:
Wenn Sie eine dreistellige Zahl konvertieren:
Wenn Sie eine vierstellige Zahl konvertieren:
Und so weiter bis zu siebenstellige Zahlen. In diesem Beispiel
n
ist eine bestimmte Ganzzahl. Nach der Konvertierung kann auf die Zeichenfolgendarstellung zugegriffen werden als(char*)&s
:HINWEIS: Wenn Sie es in Big-Endian-Bytereihenfolge benötigen, obwohl ich es nicht getestet habe, aber hier ein Beispiel: Für dreistellige Zahlen ist es
int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8;
für vierstellige Zahlen (64-Bit-Bogen):int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32;
Ich denke, es sollte funktionieren.quelle
Verwenden:
quelle
Ich benutze:
Es funktioniert auf meinen Windows- und Linux-G ++ - Compilern.
quelle
sprintf
ist bekannt dafür, Daten in eine Zeichenfolge des erforderlichen Formats einzufügen.Sie können ein
char *
Array wie in der dritten Zeile gezeigt in eine Zeichenfolge konvertieren .quelle
Das hat bei mir funktioniert -
Mein Code:
quelle
stringstream
?std::to_string()
using namespace std;
:)C ++ 11
std::to_string()
für numerische Typen eingeführt:quelle
Verwenden:
quelle
quelle
Wenn Sie MFC verwenden , können Sie Folgendes verwenden
CString
:quelle
quelle
Sie können jetzt verwenden
to_string(5)
.quelle
std
Namespace sollten Sie auch nie tun. Es scheint auch kein_MAX_INT_DIG
Standardmakro zu sein. Wenn es also falsch definiert ist, hat dieser Code das große Potenzial, undefiniertes Verhalten hervorzurufen. -1Ich denke, die Verwendung
stringstream
ist ziemlich einfach:quelle
Sie verwenden einen Zählertyp-Algorithmus, um ihn in eine Zeichenfolge zu konvertieren. Ich habe diese Technik durch Programmieren von Commodore 64- Computern erhalten. Es ist auch gut für die Spielprogrammierung.
Sie nehmen die ganze Zahl und nehmen jede Ziffer, die mit Zehnerpotenzen gewichtet ist. Nehmen wir also an, die ganze Zahl ist 950.
Wenn die Ganzzahl gleich oder größer als 100.000 ist, subtrahieren Sie 100.000 und erhöhen Sie den Zähler in der Zeichenfolge bei ["000000"];
Mach so weiter, bis keine Zahlen mehr auf Position 100.000 sind. Lass eine weitere Zehnerpotenz fallen.
Wenn die Ganzzahl gleich oder größer als 10.000 ist, subtrahieren Sie 10.000 und erhöhen Sie den Zähler in der Zeichenfolge an der Position ["000000"] + 1;
mach so weiter, bis keine Zahlen mehr auf Position 10.000 sind.
Lass eine weitere Zehnerpotenz fallen
Ich weiß, dass 950 zu klein ist, um als Beispiel zu dienen, aber ich hoffe, Sie haben die Idee.
quelle