So konvertieren Sie eine Zahl in eine Zeichenfolge und umgekehrt in C++

Lesezeit: 11 Minuten

So konvertieren Sie eine Zahl in eine Zeichenfolge und umgekehrt
Armen Tsirunjan

Da diese Frage jede Woche gestellt wird, könnte diese FAQ vielen Benutzern helfen.

  • So konvertieren Sie in C++ eine Ganzzahl in einen String

  • wie man in C++ einen String in einen Integer umwandelt

  • wie man in C++ eine Fließkommazahl in einen String umwandelt

  • wie man in C++ einen String in eine Fließkommazahl umwandelt

  • Für solche Konvertierungen habe ich ein Lesezeichen converttypes.com

    – Firzok Nadeem

    24. Juni 2020 um 19:31 Uhr

So konvertieren Sie eine Zahl in eine Zeichenfolge und umgekehrt
KillianDS

Update für C++11

Ab dem C++11 Standard, Konvertierung von Zeichenfolgen in Zahlen und umgekehrt sind in die Standardbibliothek integriert. Alle folgenden Funktionen sind in vorhanden <string> (gemäß Absatz 21.5).

Zeichenfolge zu numerisch

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

Jeder von ihnen nimmt eine Zeichenfolge als Eingabe und versucht, sie in eine Zahl umzuwandeln. Wenn keine gültige Zahl konstruiert werden konnte, weil beispielsweise keine numerischen Daten vorhanden sind oder die Zahl für den Typ außerhalb des zulässigen Bereichs liegt, wird eine Ausnahme ausgelöst (std::invalid_argument oder std::out_of_range).

Wenn die Konvertierung erfolgreich war und idx ist nicht 0, idx enthält den Index des ersten Zeichens, das nicht für die Dekodierung verwendet wurde. Dies könnte ein Index hinter dem letzten Zeichen sein.

Schließlich erlauben die ganzzahligen Typen die Angabe einer Basis, für Ziffern größer als 9 wird das Alphabet angenommen (a=10 noch bis z=35). Weitere Informationen zur genauen Formatierung, die analysiert werden kann, finden Sie hier Gleitkommazahlen, vorzeichenbehaftete ganze Zahlen und vorzeichenlose ganze Zahlen.

Schließlich gibt es für jede Funktion auch eine Überladung, die a akzeptiert std::wstring als erster Parameter.

numerisch zu Zeichenfolge

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

Diese sind einfacher, Sie übergeben den entsprechenden numerischen Typ und erhalten eine Zeichenfolge zurück. Für Formatierungsoptionen sollten Sie zur C++03-Stringsream-Option zurückkehren und Stream-Manipulatoren verwenden, wie in einer anderen Antwort hier erläutert.

Wie in den Kommentaren erwähnt, greifen diese Funktionen auf eine standardmäßige Mantissengenauigkeit zurück, die wahrscheinlich nicht die maximale Genauigkeit ist. Wenn für Ihre Anwendung mehr Präzision erforderlich ist, greifen Sie am besten auch auf andere Zeichenfolgenformatierungsverfahren zurück.

Es sind auch ähnliche Funktionen definiert, die benannt sind to_wstringdiese geben a zurück std::wstring.

  • std::to_string verliert viel Präzision für Fließkommatypen. Zum Beispiel double f = 23.4323897462387526; std::string f_str = std::to_string(f); gibt eine Zeichenfolge von 23.432390 zurück. Dies macht es unmöglich, Gleitkommawerte mit diesen Funktionen zu runden.

    – fun4jimmy

    26. November 2014 um 16:45 Uhr

  • @fun4jimmy ist dies eine Einschränkung, die durch den Standard oder eine spezifische Implementierung auferlegt wird? Werde es der Antwort hinzufügen. Nicht, dass Round-Trip Floating durch Strings jemals eine gute Idee wäre.

    – KillianDS

    27. November 2014 um 7:57 Uhr


  • Die C++ Standard sagt “Rückgaben: Jede Funktion gibt ein Zeichenfolgenobjekt zurück, das die Zeichendarstellung des Werts ihres Arguments enthält, das beim Aufrufen generiert würde sprintf(buf, fmt, val) mit einem Formatbezeichner von “%D”, “%u”, “%ld”, “%lu”, “%lld”, “%llu”, “%F”, “%F”oder “%Lf”bzw. wo buf bezeichnet einen internen Zeichenpuffer ausreichender Größe.„Ich habe mir die angeschaut C99 Standard für Druckf und ich denke, dass die Anzahl der Nachkommastellen abhängig ist #define DECIMAL_DIG in float.h.

    – fun4jimmy

    27. November 2014 um 13:39 Uhr


  • Bruce Dawson hat einige gute Artikel darüber, welche Genauigkeit für das Roundtripping von Gleitkommazahlen auf seiner Seite erforderlich ist bloggen.

    – fun4jimmy

    27. November 2014 um 13:44 Uhr

  • Alle diese Funktionen werden von der globalen Locale beeinflusst, was zu Problemen führen kann, wenn Sie Bibliotheken verwenden, insbesondere wenn Sie Threads verwenden. Siehe meine Frage hier: stackoverflow.com/questions/31977457/…

    – Ident

    13. August 2015 um 11:50 Uhr

So konvertieren Sie eine Zahl in eine Zeichenfolge und umgekehrt
Armen Tsirunjan

So konvertieren Sie eine Zahl in eine Zeichenfolge in C++03

  1. Verwende nicht der itoa oder itof Funktionen, da sie nicht standardisiert und daher nicht portierbar sind.
  2. Verwenden Sie String-Streams

     #include <sstream>  //include this to use string streams
     #include <string> 
    
    int main()
    {    
        int number = 1234;
    
        std::ostringstream ostr; //output string stream
        ostr << number; //use the string stream just like cout,
        //except the stream prints not to stdout but to a string.
    
        std::string theNumberString = ostr.str(); //the str() function of the stream 
        //returns the string.
    
        //now  theNumberString is "1234"  
    }
    

    Beachten Sie, dass Sie String-Streams auch verwenden können, um Gleitkommazahlen in Strings umzuwandeln und den String wie gewünscht zu formatieren, genau wie mit cout

    std::ostringstream ostr;
    float f = 1.2;
    int i = 3;
    ostr << f << " + " i << " = " << f + i;   
    std::string s = ostr.str();
    //now s is "1.2 + 3 = 4.2" 
    

    Sie können Stream-Manipulatoren verwenden, z std::endl, std::hex und Funktionen std::setw(), std::setprecision() etc. mit Stringstreams genauso wie mit cout

    Nicht verwechseln std::ostringstream mit std::ostrstream. Letzteres ist veraltet

  3. Verwenden lexikalische Besetzung verstärken. Wenn Sie mit Boost nicht vertraut sind, ist es eine gute Idee, mit einer kleinen Bibliothek wie dieser lexical_cast zu beginnen. Zum Herunterladen und Installieren von Boost und seiner Dokumentation Gehe hier hin. Obwohl Boost nicht im C++-Standard enthalten ist, werden viele Boost-Bibliotheken schließlich standardisiert, und Boost wird allgemein als eine der besten C++-Bibliotheken angesehen.

    Lexical Cast verwendet Streams darunter, also ist diese Option im Grunde die gleiche wie die vorherige, nur weniger ausführlich.

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       float f = 1.2;
       int i = 42;
       std::string sf = boost::lexical_cast<std::string>(f); //sf is "1.2"
       std::string si = boost::lexical_cast<std::string>(i); //sf is "42"
    }
    

Wie man in C++03 einen String in eine Zahl umwandelt

  1. Die einfachste Option, die von C geerbt wurde, sind die Funktionen atoi (für ganze Zahlen (alphabetisch zu ganzen Zahlen)) und atof (für Fließkommawerte (alphabetisch nach Float)). Diese Funktionen nehmen eine Zeichenfolge im C-Stil als Argument (const char *) und damit ihre Verwendung dürfen als nicht gerade gute C++-Praxis angesehen werden. cplusplus.com hat eine leicht verständliche Dokumentation zu beiden atoi und atof einschließlich, wie sie sich im Falle einer schlechten Eingabe verhalten. Der Link enthält jedoch den Fehler, dass laut Standard das Verhalten undefiniert ist, wenn die Eingabenummer zu groß ist, um in den Zieltyp zu passen.

    #include <cstdlib> //the standard C library header
    #include <string>
    int main()
    {
        std::string si = "12";
        std::string sf = "1.2";
        int i = atoi(si.c_str()); //the c_str() function "converts" 
        double f = atof(sf.c_str()); //std::string to const char*
    }
    
  2. Verwenden Sie String-Streams (diesmal geben Sie String-Stream ein, istringstream). Auch hier wird istringstream wie verwendet cin. Auch hier nicht verwechseln istringstream mit istrstream. Letzteres ist veraltet.

    #include <sstream>
    #include <string>
    int main()
    {
       std::string inputString = "1234 12.3 44";
       std::istringstream istr(inputString);
       int i1, i2;
       float f;
       istr >> i1 >> f >> i2;
       //i1 is 1234, f is 12.3, i2 is 44  
    }
    
  3. Verwenden lexikalische Besetzung verstärken.

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       std::string sf = "42.2"; 
       std::string si = "42";
       float f = boost::lexical_cast<float>(sf); //f is 42.2
       int i = boost::lexical_cast<int>(si);  //i is 42
    }       
    

    Im Falle einer schlechten Eingabe, lexical_cast löst eine Ausnahme vom Typ aus boost::bad_lexical_cast

  • Die cplusplus-Dokumentation für atoi ist nicht ausgezeichnet, es ist falsch. Es wird nicht erwähnt, dass, wenn der numerische Wert der Zeichenfolge nicht dargestellt werden kann int, dann ist das Verhalten undefiniert. Stattdessen heißt es, dass Werte außerhalb des Bereichs geklemmt werden INT_MAX/INT_MIN, die ich weder in C++03 noch in C89 finden kann. Für nicht vertrauenswürdige/nicht verifizierte Eingaben oder beim Umgang mit Basen, die von Streams nicht unterstützt werden, benötigen Sie strtol, die ein definiertes Fehlerverhalten hat. Und ähnliche Kommentare für atof/strtod.

    – Steve Jessop

    13. März 2011 um 15:03 Uhr


  • cplusplus.com ist falsch mit “atoi”. Über den Rückgabewert heißt es: „Wenn keine gültige Konvertierung durchgeführt werden konnte, wird ein Nullwert zurückgegeben. Wenn der korrekte Wert außerhalb des Bereichs darstellbarer Werte liegt, wird INT_MAX oder INT_MIN zurückgegeben.“ Wert des Ergebnisses kann nicht dargestellt werden, das Verhalten ist undefiniert.” und dass “Mit Ausnahme des Fehlerverhaltens sind sie äquivalent zu (int)strtol(nptr, (char **)NULL, 10). Die Atois[…] Funktionen geben den konvertierten Wert zurück.”. cplusplus.com ist dafür bekannt, eine unglaublich schlechte Informationsquelle für Anfänger zu sein.

    – Johannes Schaub – litb

    13. März 2011 um 15:07 Uhr


  • istr >> i1 >> f >> i2; eine Erfolgskontrolle verpasst.

    – sbi

    26. Mai 2011 um 18:16 Uhr

  • Möchte vielleicht hinzufügen std::to_string

    – Kneipe

    9. Mai 2012 um 5:09 Uhr

  • @ArmenTsirunyan: +10 von meiner Seite, Eine der besten Antworten, die ich je gesehen habe, auch in der Tiefe. Danke für deine Antwort.

    – Abhineet

    29. Juni 2012 um 11:23 Uhr

1647132610 491 So konvertieren Sie eine Zahl in eine Zeichenfolge und umgekehrt
JiaHao Xu

In C++17 neue Funktionen std::to_chars und std::from_chars werden in der Kopfzeile eingeführt charconv.

std::to_chars ist gebietsschemaunabhängig, nicht zuweisend und nicht werfend.

Es wird nur eine kleine Teilmenge von Formatierungsrichtlinien bereitgestellt, die von anderen Bibliotheken (z. B. std::sprintf) verwendet werden.

Von std::to_charsdas gleiche für std::from_chars.

Die Garantie, dass std::from_chars jeden von to_chars formatierten Fließkommawert exakt wiederherstellen kann, ist nur gegeben, wenn beide Funktionen aus derselben Implementierung stammen

 // See en.cppreference.com for more information, including format control.
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <charconv>

using Type =  /* Any fundamental type */ ;
std::size_t buffer_size = /* ... */ ;

[[noreturn]] void report_and_exit(int ret, const char *output) noexcept 
{
    std::printf("%s\n", output);
    std::exit(ret);
}
void check(const std::errc &ec) noexcept
{
    if (ec ==  std::errc::value_too_large)
        report_and_exit(1, "Failed");
}
int main() {
    char buffer[buffer_size];        
    Type val_to_be_converted, result_of_converted_back;

    auto result1 = std::to_chars(buffer, buffer + buffer_size,  val_to_be_converted);
    check(result1.ec);
    *result1.ptr="\0";

    auto result2 = std::from_chars(buffer, result1.ptr, result_of_converted_back);
    check(result2.ec);

    assert(val_to_be_converted == result_of_converted_back);
    report_and_exit(0, buffer);
}

Obwohl es von Compilern noch nicht vollständig implementiert ist, wird es definitiv implementiert werden.

Ich habe diese praktische Klasse irgendwo hier bei StackOverflow gestohlen, um alles, was streambar ist, in einen String zu konvertieren:

// make_string
class make_string {
public:
  template <typename T>
  make_string& operator<<( T const & val ) {
    buffer_ << val;
    return *this;
  }
  operator std::string() const {
    return buffer_.str();
  }
private:
  std::ostringstream buffer_;
};

Und dann verwenden Sie es als;

string str = make_string() << 6 << 8 << "hello";

Ziemlich raffiniert!

Außerdem verwende ich diese Funktion, um Zeichenfolgen in alles zu konvertieren, was streambar ist, obwohl es nicht sehr sicher ist, wenn Sie versuchen, eine Zeichenfolge zu analysieren, die keine Zahl enthält.
(und es ist auch nicht so schlau wie das letzte)

// parse_string
template <typename RETURN_TYPE, typename STRING_TYPE>
RETURN_TYPE parse_string(const STRING_TYPE& str) {
  std::stringstream buf;
  buf << str;
  RETURN_TYPE val;
  buf >> val;
  return val;
}

Benutzen als:

int x = parse_string<int>("78");

Möglicherweise möchten Sie auch Versionen für wstrings.

#include <iostream>
#include <string.h>
using namespace std;
int main() {
   string s="000101";
   cout<<s<<"\n";
   int a = stoi(s);
   cout<<a<<"\n";
   s=to_string(a);
   s+='1';
   cout<<s;
   return 0;
}

Ausgabe:

  • 000101
  • 101
  • 1011

  • HI, die Antwort ist unvollständig (keine Gleitkommakonvertierungen) und auch falsch (to_string ist nicht definiert). Bitte achten Sie darauf, nützliche Antworten zu geben

    – Massimo Costa

    16. Oktober 2020 um 19:40 Uhr

  • HI, die Antwort ist unvollständig (keine Gleitkommakonvertierungen) und auch falsch (to_string ist nicht definiert). Bitte achten Sie darauf, nützliche Antworten zu geben

    – Massimo Costa

    16. Oktober 2020 um 19:40 Uhr

995500cookie-checkSo konvertieren Sie eine Zahl in eine Zeichenfolge und umgekehrt in C++

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy