769 Stimmen

Wie kann ich einen std::string in int umwandeln?

Ich möchte einen String in einen int konvertieren, und ich meine nicht ASCII-Codes.

Für einen schnellen Durchlauf wird uns eine Gleichung als String übergeben. Wir sollen sie aufschlüsseln, richtig formatieren und die linearen Gleichungen lösen. Ich bin nicht in der Lage, eine Zeichenkette in eine Zahl zu konvertieren.

Ich weiß, dass die Zeichenfolge entweder im Format (-5) oder (25) usw. sein wird, also ist es definitiv ein int. Aber wie extrahieren wir das aus einem String?

Eine Möglichkeit, die ich dachte, ist das Ausführen einer for/while-Schleife durch die Zeichenfolge, überprüfen Sie für eine Ziffer, extrahieren Sie alle Ziffern nach, dass und dann zu sehen, wenn es eine führende '-', wenn es ist, multiplizieren Sie die int mit -1.

Für ein so kleines Problem scheint es allerdings etwas zu kompliziert zu sein. Irgendwelche Ideen?

1114voto

tgmath Punkte 12013

In C++11 gibt es einige schöne neue Konvertierungsfunktionen von std::string zu einem Zahlentyp.

Anstatt also

atoi( str.c_str() )

können Sie

std::stoi( str )

wobei str ist Ihre Nummer als std::string .

Es gibt Versionen für alle Arten von Zahlen: long stol(string) , float stof(string) , double stod(string) ,... siehe http://en.cppreference.com/w/cpp/string/basic_string/stol

110voto

Claudio Punkte 10063

Die möglichen Optionen werden im Folgenden beschrieben:

1. sscanf()

    #include <cstdio>
    #include <string>

        int i;
        float f;
        double d;
        std::string str;

        // string -> integer
        if(sscanf(str.c_str(), "%d", &i) != 1)
            // error management

        // string -> float
        if(sscanf(str.c_str(), "%f", &f) != 1)
            // error management

        // string -> double 
        if(sscanf(str.c_str(), "%lf", &d) != 1)
            // error management

Dies ist ein Fehler (auch von cppcheck angezeigt), weil "scanf ohne Feldbreitenbegrenzung kann bei großen Eingabedaten in einigen Versionen von libc abstürzen" (siehe ici y ici ).

_2. std::sto ()_ *

    #include <iostream>
    #include <string>

        int i;
        float f;
        double d;
        std::string str;

        try {
            // string -> integer
            int i = std::stoi(str);

            // string -> float
            float f = std::stof(str);

            // string -> double 
            double d = std::stod(str);
        } catch (...) {
            // error management
        }   

Diese Lösung ist kurz und elegant, aber sie ist nur auf C++11-kompatiblen Compilern verfügbar.

3. sStreams

    #include <string>
    #include <sstream>

        int i;
        float f;
        double d;
        std::string str;

        // string -> integer
        std::istringstream ( str ) >> i;

        // string -> float
        std::istringstream ( str ) >> f;

        // string -> double 
        std::istringstream ( str ) >> d;

        // error management ??

Bei dieser Lösung ist es jedoch schwierig, zwischen schlechten Eingaben zu unterscheiden (siehe ici ).

4. Boosts lexical_cast

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

        std::string str;

        try {
            int i = boost::lexical_cast<int>( str.c_str());
            float f = boost::lexical_cast<int>( str.c_str());
            double d = boost::lexical_cast<int>( str.c_str());
            } catch( boost::bad_lexical_cast const& ) {
                // Error management
        }

Dies ist jedoch nur eine Umhüllung von sstream und die Dokumentation empfiehlt die Verwendung von sstream für ein besseres Fehlermanagement (siehe ici ).

_5. strto ()_ *

Diese Lösung ist wegen der Fehlerbehandlung sehr lang und wird hier beschrieben. Da keine Funktion einen einfachen int zurückgibt, ist im Falle von integer eine Konvertierung erforderlich (siehe ici wie diese Umwandlung erreicht werden kann).

6. Qt

    #include <QString>
    #include <string>

        bool ok;
        std::string;

        int i = QString::fromStdString(str).toInt(&ok);
        if (!ok)
            // Error management

        float f = QString::fromStdString(str).toFloat(&ok);
        if (!ok)
            // Error management 

        double d = QString::fromStdString(str).toDouble(&ok);
        if (!ok)
    // Error management     

Schlussfolgerungen

Zusammenfassend lässt sich sagen, dass die beste Lösung C++11 ist. std::stoi() oder, als zweite Option, die Verwendung von Qt-Bibliotheken. Von allen anderen Lösungen wird abgeraten oder sie sind fehlerhaft.

69voto

Winston Ewert Punkte 42219
std::istringstream ss(thestring);
ss >> thevalue;

Um ganz sicher zu gehen, sollten Sie die Fehlerkennzeichen überprüfen.

56voto

Pascal H. Punkte 1103

Der Vollständigkeit halber (und weil in den Kommentaren darum gebeten wurde), füge ich die Lösung von C++17 hinzu, die std::from_chars .

std::string str = "10";
int number;
std::from_chars(str.data(), str.data()+str.size(), number);

Wenn Sie überprüfen wollen, ob die Konvertierung erfolgreich war:

std::string str = "10";
int number;
auto [ptr, ec] = std::from_chars(str.data(), str.data()+str.size(), number);
assert(ec == std::errc{});
// ptr points to chars after read number

Um die Leistung all dieser Lösungen zu vergleichen, klicken Sie auf den folgenden Quick-Bench-Link: https://quick-bench.com/q/GBzK53Gc-YSWpEA9XskSZLU963Y

( std::from_chars ist die schnellste und std::istringstream ist die langsamste)

52voto

brenjt Punkte 15551

Verwenden Sie die Funktion atoi, um die Zeichenkette in eine ganze Zahl umzuwandeln:

string a = "25";

int b = atoi(a.c_str());

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X