Der einfachste Weg, int in C ++ in einen String zu konvertieren


1574

Was ist der einfachste Weg, um in C ++ von inteinem Äquivalent zu konvertieren? stringMir 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();

4
Ich denke, beide Methoden, die Sie angegeben haben, sind gute Lösungen. Dies hängt vom Kontext ab, in dem Sie dies tun müssen. Wenn Sie bereits mit Streams arbeiten, z. B. eine Datei lesen oder schreiben, ist Ihre zweite Methode die beste. Wenn Sie ein int als Zeichenfolge an ein Funktionsargument übergeben müssen, ist itoa möglicherweise ein einfacher Weg. In den meisten Fällen erfolgt die Konvertierung von int in Zeichenfolgen beim Umgang mit Dateien, sodass Streams geeignet sind.
Charles Brunet

41
Wie funktioniert Option 1 überhaupt für Sie? Nach meinem Verständnis sind itoa()drei Parameter erforderlich.
b1nary.atr0phy

1
itoa ist schneller als das Stream-Äquivalent. Es gibt auch Möglichkeiten, den Zeichenfolgenpuffer mit der itoa-Methode wiederzuverwenden (Vermeidung von Heap-Zuweisungen, wenn Sie häufig Zeichenfolgen generieren, z. B. für eine schnell aktualisierte numerische Ausgabe). Alternativ können Sie einen benutzerdefinierten Streambuf generieren, um einen Teil des Zuordnungsaufwands usw. zu reduzieren. Das Erstellen des Streams ist ebenfalls kein kostengünstiges Unterfangen.
Pete

6
@Pete: Sobald Sie anfangen, sich Gedanken darüber zu machen, was schneller ist, sollten Sie sich stackoverflow.com/questions/4351371/… ansehen
Ben Voigt

20
Beachten Sie, dass itoa () nicht Teil des Standards ist. Wenn Sie es daher verwenden, wird Ihr Code nicht portierbar, da ihn nicht alle Compiler unterstützen. Unter Linux sind Sie mit Sicherheit unterwegs, es sei denn, Sie verwenden etwas anderes als GCC, das diese Funktion nicht unterstützt. Wenn Sie C ++ 0x haben, gehen Sie zu dem, was @Matthieu in seiner Antwort vorgeschlagen hat. Wenn dies nicht der Fall ist, wählen Sie stringstream, da dies eine gut unterstützte Funktion ist und Ihr Code mit jedem C ++ - Compiler kompatibel sein sollte. Alternativ können Sie immer mit sprintf () arbeiten.
Rbaleksandar

Antworten:


2102

C ++ 11 führt std::stoi(und Varianten für jeden numerischen Typ) und std::to_stringdie Gegenstücke des C ein atoiund wird itoajedoch in Term ausgedrückt std::string.

#include <string> 

std::string s = std::to_string(42);

ist daher der kürzeste Weg, den ich mir vorstellen kann. Sie können sogar die Benennung des Typs mit dem autoSchlüsselwort weglassen :

auto s = std::to_string(42);

Hinweis: siehe [string.conversions] ( 21,5 in n3242 )


199
to_stringkein Mitglied von stdfix: stackoverflow.com/questions/12975341/…
Ben

36
Oder setzen Sie je nach Compiler einfach den richtigen Sprachstandard:g++ -std=c++11 someFile.cc
Thomas M. DuBuisson

12
@Steve: soll es sein. Es ist ein Mitglied stdin jedem Compiler, den ich kenne, bis auf einen.
Mooing Duck

5
@ Matthiew M. Ich verwende das gleiche, das Sie vorschlagen, aber ich Error : No instance of overloaded function "std::to_string" matches the argument list erhalte diesen Fehler: Ich verwende VS2010 c ++

19
@Flying: Unter VS2010 müssen Sie die konvertierende Ganzzahl explizit in einen der folgenden Typen umwandeln [_Longlong, _ULonglong, long double]; dh:string s = to_string((_ULonglong)i);
Zac

184

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.

// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
    std::ostringstream sstr;
    // fold expression
    ( sstr << std::dec << ... << args );
    return sstr.str();
}

Verwendungszweck:

int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );

Ursprüngliche Antwort:

Da "Konvertieren ... in Zeichenfolge" ein wiederkehrendes Problem ist, definiere ich das Makro SSTR () immer in einem zentralen Header meiner C ++ - Quellen:

#include <sstream>

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

Die Verwendung ist so einfach wie möglich:

int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );

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önnen lexical_cast<>). Diese beiden anderen Lösungen weisen jedoch eine bessere Leistung auf.


2
Ich bin nicht sehr vertraut mit, dynamic_castaber ich benutze Clang zum Kompilieren, damit es sich darüber beschwert. Wenn ich das einfach weglasse, dynamic_castwird es gut kompiliert; Welchen Zweck hat das dynamic_castin diesem Fall? Wir erstellen bereits eine ostringstream, warum also besetzen?
Mathew

2
@Mathew: Der Link in meiner Antwort führt zu einer detaillierten Beschreibung jedes Teils des Konstrukts. Während wir erstellt ein ostringstream, riefen wir operator<<()darauf, die Erträge ostream &- 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.
DevSolar

5
Bin gerade aus Neugier zur Party gekommen und habe herabgestimmt. Grund: Zu viele Stimmen für eine Lösung, die nicht elegant und wahrscheinlich langsam ist. 1. Makronutzung. Ich runzele kein Makro systematisch die Stirn, aber dieses ist zu kurz, und Endkunden befürchten immer die Wiederholung des Arguments, zusätzlich zu der Angst vor ungeschützten mehrzeiligen Makros. (nicht geschützt durch do {} while (0)) 2. dynamic_cast. Anscheinend benötigen Sie hier nur einen static_cast, es sei denn, Sie möchten behaupten, dass die Bibliothek tatsächlich so implementiert ist, wie Sie es sich erhoffen. In diesem Fall sollten Sie stattdessen boost :: polymorphic_downcast verwenden.
v.oddou

2
@ v.oddou: Du kannst natürlich frei kritisieren. Aber 1. ist ungültig - das Makro ist eine einzelne Anweisung, 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.
DevSolar

1
@ v.oddou: Schau dir an, was ich unter den Dingen gefunden habe, die C ++ 17 uns gebracht hat. :-) Ich hoffe dir gefällt die aktualisierte Antwort.
DevSolar

109

Normalerweise verwende ich die folgende Methode:

#include <sstream>

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }

Es wird im Detail beschrieben hier .


2
Vor der Verwendung ssmüssen Sie ss.clear()es. Ich habe unerwartete Ergebnisse ohne diese Initialisierung gesehen.
Lebensbalance

14
@lifebalance: Ich habe noch nie ein solches Verhalten gesehen.
Rasoul

18
@lifebalance: Sie müssen kein clear()neu erstelltes ostringstreamObjekt erstellen . clear()Setzt die Fehler- / Eof-Flags zurück und es wurde noch keine Fehler- / Eof-Bedingung generiert.
Remy Lebeau

2
@Rasoul NumberToString(23213.123)produziert 23213.1während std::to_string(23213.123)produziert 23213.123000Was passiert dort?
Killzone Kid

1
@KillzoneKid Dies liegt daran, dass std 'ostream statusbehaftet sind (dies bedeutet, dass alle vorherigen Statusänderungen wie die Anzahl der Dezimalstellen beibehalten werden), während diese Methode mit einem Standardstatus beginnt.
xryl669

85

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 :

int a = 10;
string s = lexical_cast<string>(a);

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 konnte int(z. B. 1234wäre erfolgreich, 123abcwürde aber werfen). .

Ab C ++ 11 ist eine std::to_stringFunktion für Ganzzahltypen überladen, sodass Sie Code wie folgt verwenden können:

int a = 20;
std::string s = std::to_string(a);
// or: auto s = std::to_string(a);

Der Standard definiert diese als äquivalent zur Konvertierung mit sprintf(unter Verwendung des Konvertierungsspezifizierers, der dem angegebenen Objekttyp entspricht, z. B. %dfür int) in einen Puffer mit ausreichender Größe und anschließendem Erstellen eines std::stringInhalts dieses Puffers.


2
Schön, ich bevorzuge Kevins Antwort, da er das Include und den Namespace zeigt. Nur ein kleiner Kritikpunkt. :) Gute Arbeit!
Jason R. Mick

4
Ich würde sagen, dies ist der richtige Weg, wenn Sie keine C ++ 11-Unterstützung haben.
Alex

40

Wenn Sie Boost installiert haben (was Sie sollten):

#include <boost/lexical_cast.hpp>

int num = 4;
std::string str = boost::lexical_cast<std::string>(num);

4
Einigung über die Boost-Installation. Ich denke, dass man den String mehr als oft formatieren würde. Zu diesem Zweck bevorzuge ich boost :: format, zB format ("% 02d", number) .str ()
Werner Erasmus

28

Es wäre einfacher, Stringstreams zu verwenden:

#include <sstream>

int x = 42;          // The integer
string str;          // The string
ostringstream temp;  // 'temp' as in temporary
temp << x;
str = temp.str();    // str is 'temp' as string

Oder machen Sie eine Funktion:

#include <sstream>

string IntToString(int a)
{
    ostringstream temp;
    temp << a;
    return temp.str();
}

18

Nicht das ich wüsste, in reinem C ++. Aber eine kleine Modifikation von dem, was Sie erwähnt haben

string s = string(itoa(a));

sollte funktionieren, und es ist ziemlich kurz.


55
itoa()ist keine Standardfunktion!
Karikaturist

4
@ Cartoonist: Was ist es dann?
user541686

20
Diese Funktion ist in ANSI-C und C ++ nicht definiert. Daher wird es von einigen Compilern wie g ++ nicht unterstützt.
Karikaturist

17

Sie können std::to_stringverfügbar in C ++ 11 verwenden, wie von Matthieu M vorgeschlagen :

std::to_string(42);

Wenn die Leistung kritisch ist (z. B. wenn Sie viele Konvertierungen durchführen), können Sie fmt::format_intaus der {fmt} -Bibliothek eine Ganzzahl konvertieren in std::string:

fmt::format_int(42).str();

Oder eine C-Zeichenfolge:

fmt::format_int f(42);
f.c_str();

Letzterer führt keine dynamischen Speicherzuweisungen durch und ist mehr als zehnmal schneller als std::to_stringbei 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_interfordert nicht C ++ 11 und funktioniert mit jedem C ++ Compiler.

Haftungsausschluss: Ich bin der Autor der {fmt} -Bibliothek.


2
Ich war neugierig auf die Behauptung, keine dynamische Speicherzuweisung zu haben, während sie threadsicher bleiben (Wiedereintritt), also habe ich Ihren Code gelesen - der c_str()gibt einen Zeiger auf einen in der fmt::FormatIntKlasse deklarierten Puffer zurück - damit der zurückgegebene Zeiger bei ungültig wird das Semikolon - siehe auch stackoverflow.com/questions/4214153/lifetime-of-temporaries
Soren

1
Ja, das gleiche Verhalten wie bei std::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.
Vitaut

1
Ich bekomme etwas Seltsames, wenn ich versuche, mit std :: to_string (num) von int in string zu konvertieren. Wenn ich das Ergebnis in einer Variablen speichere und versuche, wie stringNum [1] oder stringNum [n] darauf zuzugreifen, wenn n zunimmt, erhalte ich Müll.
user8951490

1
Das ist definitiv die richtige Antwort auf diese Frage: effizienter und standardmäßiger Code, der nicht zustandsbehaftet ist.
Xryl669

16

sprintf()ist ziemlich gut für die Formatkonvertierung. Sie können dann die resultierende C-Zeichenfolge der C ++ - Zeichenfolge wie in 1 zuweisen.


1
Heh ja. Normalerweise verlasse ich mich jedoch auf snprintf () und Freunde, wenn es um den Umgang mit C-Strings geht.
Throwback1986

1
@MatthieuM. Ihr Kommentar beweist weiter, dass Sie es nicht sind. Wenn die Ausgabe aufgrund dieser Grenze abgeschnitten wurde, ist der Rückgabewert die Anzahl der Zeichen (ohne das abschließende Nullbyte), die in die endgültige Zeichenfolge geschrieben worden wären, wenn genügend Speicherplatz verfügbar gewesen wäre. Ein Rückgabewert von Größe oder mehr bedeutet also, dass die Ausgabe abgeschnitten wurde. Sie rufen es also mit einer NULLGröße von Null auf, um die erforderliche Puffergröße zu erhalten.
user1095108

2
@ user1095108: Ich denke, Sie irren sich snprintf(beachten Sie das SNP- Präfix) und sprintf(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.
Matthieu M.

1
Die Idee ist, zuerst eine snprintfVariante und danach eine sprintfVariante aufzurufen . Da die Puffergröße bis dahin bekannt ist, sprintfwird das Aufrufen völlig sicher.
user1095108

1
@ user1095108 Ah, ja. Wenn der erste Puffer für snprintf nicht ausreicht, gibt der Rückgabewert an, was ausreichen würde. Ich würde immer noch snprintf für den zweiten Aufruf verwenden, da es unnötig gefährlich ist, sich auf die Implementierungen von sprintf und snprintf zu verlassen, um eine Übereinstimmung zu erzielen.
Mabraham

11

Zuerst umfassen:

#include <string>
#include <sstream>

Zweitens fügen Sie die Methode hinzu:

template <typename T>
string NumberToString(T pNumber)
{
 ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

Verwenden Sie die Methode wie folgt:

NumberToString(69);

oder

int x = 69;
string vStr = NumberToString(x) + " Hello word!."

10

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 = 1000beispielsweise in einen String konvertiert werden 1.001. Dies könnte dazu führen, dass Vergleichsoperationen überhaupt nicht funktionieren.

Daher würde ich die Verwendung des std::to_stringWeges dringend empfehlen . Es ist einfacher und macht das, was Sie erwarten.

Aktualisiert (siehe Kommentare unten) :

C ++ 17 bietet std::to_charseine leistungsstärkere, vom Gebietsschema unabhängige Alternative


2
Ich bin damit einverstanden, dass dies ein ernstes Problem ist, wenn Sie Daten austauschen müssen. std::to_stringVerwendet leider auch das aktuelle Gebietsschema (siehe en.cppreference.com/w/cpp/string/basic_string/to_string , Abschnitt 'Notizen'). Fast alle Standardtools (von Stringstreams bis sprintfaber auch sscanfusw.) 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.
Bert Bril

Im obigen Link ist es auch statet, dass C ++ 17 std :: to_chars als leistungsstärkere, vom Gebietsschema unabhängige Alternative bereitstellt.
YesThatIsMyName

Leider bin ich für die kommenden Jahre mit C ++ 11 festgefahren (zum Glück schon eine ziemliche Verbesserung).
Bert Bril

1
from_chars und to_chars wären perfekt, aber leider haben sie keine wchar_t-Variante angeboten.
Gast128

8

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.

Die lexical_castFunktionsvorlage bietet eine bequeme und konsistente Form zur Unterstützung gängiger Konvertierungen von und zu beliebigen Typen, wenn diese als Text dargestellt werden.
- Boosts Dokumentation

#include "boost/lexical_cast.hpp"
#include <string>

int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast<std::string>(x);
    return 0;
}

Was die Laufzeit betrifft, lexical_castdauert 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

Diese Funktion ist in ANSI-C nicht definiert und nicht Teil von C ++, wird jedoch von einigen Compilern unterstützt.
- cplusplus.com

Dies bedeutet, dass gcc/ g++Code nicht mit kompiliert werden kann itoa.

#include <stdlib.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    x_str = itoa(x, x_str, 10); // base 10
    return 0;
}

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.

Erstellt eine Zeichenfolge mit demselben Text, der gedruckt würde, wenn das Format für printf verwendet würde. Statt gedruckt zu werden, wird der Inhalt als C-Zeichenfolge in dem Puffer gespeichert, auf den str zeigt.
- cplusplus.com

#include <stdio.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    int chars_written = sprintf(x_str, "%d", x);
    return 0;
}

Der stdio.hHeader ist möglicherweise nicht erforderlich. Was die Laufzeit betrifft, sprintfdauert 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 z ostringstream. Die Verwendung ostringstreamteilt 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.

#include <sstream>
#include <string>

int main() {
    int x = 5;
    std::ostringstream stream;
    stream << x;
    std::string x_str = stream.str();
    return 0;
}

Was die Laufzeit betrifft, ostringstreamdauert 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.


Vielen Dank für die
A. B

@AB Ich kann nicht glauben, dass noch C ++ 98-Benutzer übrig sind.
Kotauskas

@VladislavToncharov Wenn Ihre Aufgabe ausschließlich darin besteht, ältere Geräte und Codes zu unterstützen, mischen Sie die alten Dinge nach neueren Industriestandards ein. Vor einem Sommer habe ich Code in Python 2.3 geschrieben.
Joshua Detwiler

@ JoshuaDetwiler Oh, das habe ich vergessen, sorry.
Kotauskas

4

C ++ 17 bietet std :: to_chars als leistungsstärkere, vom Gebietsschema unabhängige Alternative.


3

Es ist ziemlich einfach, etwas syntaktischen Zucker hinzuzufügen, der es einem ermöglicht, Strings im laufenden Betrieb stromartig zu komponieren

#include <string>
#include <sstream>

struct strmake {
    std::stringstream s;
    template <typename T> strmake& operator << (const T& x) {
        s << x; return *this;
    }   
    operator std::string() {return s.str();}
};

Jetzt können Sie anhängen, was Sie möchten (vorausgesetzt, ein Operator << (std::ostream& ..)ist dafür definiert), strmake()und es anstelle von verwenden std::string.

Beispiel:

#include <iostream>

int main() {
    std::string x =
      strmake() << "Current time is " << 5+5 << ":" << 5*5 << " GST";
    std::cout << x << std::endl;
}

2

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:

int32_t s = 0x3030 | (n/10) | (n%10) << 8;

Wenn Sie eine dreistellige Zahl konvertieren:

int32_t s = 0x303030 | (n/100) | (n/10%10) << 8 | (n%10) << 16;

Wenn Sie eine vierstellige Zahl konvertieren:

int64_t s = 0x30303030 | (n/1000) | (n/100%10)<<8 | (n/10%10)<<16 | (n%10)<<24;

Und so weiter bis zu siebenstellige Zahlen. In diesem Beispiel nist eine bestimmte Ganzzahl. Nach der Konvertierung kann auf die Zeichenfolgendarstellung zugegriffen werden als (char*)&s:

std::cout << (char*)&s << std::endl;

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.


2
Was ist mit der Bytereihenfolge?
Shjeff

Liegt dieses undefinierte Verhalten nicht am Zeiger-Aliasing?
dgnuff

1
@shjeff danke für den Kommentar, ich habe der Antwort einen Hinweis zur Endianness hinzugefügt.
Alek

@dgnuff danke für den Hinweis, obwohl ich keine Probleme damit hatte, hast du recht. Ich habe die Antwort leicht geändert, damit sie den strengen Aliasing-Regeln entspricht, danke.
Alek

1

Verwenden:

#define convertToString(x) #x

int main()
{
    convertToString(42); // Returns const char* equivalent of 42
}

3
Funktioniert nur mit Literalzahlen, wertet den variablen Inhalt nicht aus, ist aber manchmal nützlich.
Wolf

Recht. Aber auf jeden Fall zur Zeit praktisch
maverick9888

1
Funktioniert nur zur Kompilierungszeit mit Literal-Konstanten-Zahlen. Ich denke, das OP fordert eine dynamische Konvertierung unter Verwendung variabler Ganzzahlen
Ing. Gerardo Sánchez

0

Ich benutze:

int myint = 0;
long double myLD = 0.0;

string myint_str = static_cast<ostringstream*>(&(ostringstream() << myint))->str();
string myLD_str = static_cast<ostringstream*>(&(ostringstream() << myLD))->str();

Es funktioniert auf meinen Windows- und Linux-G ++ - Compilern.


0

Hier ist eine weitere einfache Möglichkeit

char str[100];
sprintf(str, "%d", 101);
string s = str;

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 .


0

Das hat bei mir funktioniert -

Mein Code:

#include <iostream>
using namespace std;

int main()
{
    int n = 32;
    string s = to_string(n);
    cout << "string: " + s  << endl;
    return 0;
}

Im Wesentlichen mit was? stringstream?
Peter Mortensen

@ PeterMortensen Schau genau hin, es iststd::to_string()
Kotauskas

Ich habe using namespace std;:)
Gonçalo Garrido

0

C ++ 11 std::to_string()für numerische Typen eingeführt:

int n = 123; // Input, signed/unsigned short/int/long/long long/float/double
std::string str = std::to_string(n); // Output, std::string

4
Hallo! Können Sie eine Erklärung hinzufügen, warum und wie dies eine Antwort auf die Frage liefert?
Anothernode

0

Verwenden:

#include<iostream>
#include<string>

std::string intToString(int num);

int main()
{
    int integer = 4782151;

    std::string integerAsStr = intToString(integer);

    std::cout << "integer = " << integer << std::endl;
    std::cout << "integerAsStr = " << integerAsStr << std::endl;

    return 0;
}

std::string intToString(int num)
{
    std::string numAsStr;

    while (num)
    {
        char toInsert = (num % 10) + 48;
        numAsStr.insert(0, 1, toInsert);

        num /= 10;
    }
    return numAsStr;
}

1
Scheitert komplett für n≤0
Toby Speight

-1
string number_to_string(int x) {

    if (!x)
        return "0";

    string s, s2;
    while(x) {
        s.push_back(x%10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return s;
}

1
Vielen Dank für dieses Code-Snippet, das möglicherweise nur begrenzte kurzfristige Hilfe bietet. Eine richtige Erklärung würde ihren langfristigen Wert erheblich verbessern, indem sie zeigt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen, ähnlichen Fragen nützlicher machen. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der von Ihnen getroffenen Annahmen.
Toby Speight

Scheitert komplett für n≤0
Toby Speight

Fügen Sie Kommentare hinzu, erklären Sie Ihre Antwort und lesen Sie, wie Sie antworten .
Aksen P

-1

Wenn Sie MFC verwenden , können Sie Folgendes verwenden CString:

int a = 10;
CString strA;
strA.Format("%d", a);

8
Sie sollten beachten, dass dies eine reine
JonnyJD

1
Ich liebe die Idee von CString :: Format (). Leider ist es nicht tragbare MS nur.
Nick

1
Ich habe meine Antwort aktualisiert, um die Informationen aus Ihrem Kommentar @JonnyJD aufzunehmen, da ich 5 Jahre später immer wieder dafür herabgestimmt werde.
Tur1ng

-2
char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs, "%d", timeStart.elapsed()/1000);
sprintf(bufMs, "%d", timeStart.elapsed()%1000);

12
leckt Speicher, -1 von mir
Paulm

Dies riecht nach Pufferüberlauf.
Kotauskas

-2
namespace std
{
    inline string to_string(int _Val)
    {   // Convert long long to string
        char _Buf[2 * _MAX_INT_DIG];
        snprintf(_Buf, "%d", _Val);
        return (string(_Buf));
    }
}

Sie können jetzt verwenden to_string(5).


10
Obwohl diese Lösung funktioniert, wird dringend davon abgeraten! Namen, die mit einem Unterstrich und einem Großbuchstaben beginnen, sind für den Compiler reserviert. Sie sollten sie niemals verwenden. Das Injizieren von Funktionen in den stdNamespace sollten Sie auch nie tun. Es scheint auch kein _MAX_INT_DIGStandardmakro zu sein. Wenn es also falsch definiert ist, hat dieser Code das große Potenzial, undefiniertes Verhalten hervorzurufen. -1
iFreilicht

6
Was ist _MAX_INT_DIG und warum wird es verdoppelt?
Paulm

-2

Ich denke, die Verwendung stringstreamist ziemlich einfach:

 string toString(int n)
 {
     stringstream ss(n);
     ss << n;
     return ss.str();
 }

 int main()
 {
    int n;
    cin >> n;
    cout << toString(n) << endl;
    return 0;
 }

Dies wurde in der Frage erwähnt und ist leider ziemlich langsam.
Kotauskas

-3

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

  • Wiederholen Sie das Muster

Ich weiß, dass 950 zu klein ist, um als Beispiel zu dienen, aber ich hoffe, Sie haben die Idee.


Es ist nicht sehr hilfreich, einen Algorithmus zu beschreiben, anstatt ein Beispiel im Code zu zeigen.
Cdeerinck
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.