vollständige string -> int/double Konvertierung
-
Hallo,
wie löse ich am besten folgendes Problem: Ich habe einen String und möchte ihn nach int/double konvertieren. Dabei müssen alle Zeichen des Strings berücksichtigt werden, sodass der komplette String entweder eine gültige Zahl darstellt oder nicht. Die C++/C Methode parsen nur bis zum ersten ungültigen Zeichen, damit ist mir leider nicht geholfen.
-
Schau bitte in die FAQ, Thread "einmal zahl nach string und zurück". Tip: wenn nach dem auslesen der zahl aus dem stringstream noch was drinsteht konnte es offenbar nicht komplett als Zahl geparst werden.
-
Danke pumuckl, Asche über mein Haupt. Ich habe ein paar Versuche unternommen um die Anzahl der noch im Stream befindlichen Zeichen zu bekommen, aber gegen eof() zu prüfen ist mir nicht eingefallen.
-
DocShoe schrieb:
Ich habe ein paar Versuche unternommen um die Anzahl der noch im Stream befindlichen Zeichen zu bekommen
Wäre auch mein Ansatz, imo zumindest besser als gegen eof() zu testen.
std::string maybeanumber; /* ... */ int i; std::stringstream stream(maybeanumber); stream >> i; bool itwasanumber = !stream.fail() && (stream.str().size() == 0);tut nicht?
-
Nein, das hab ich schon probiert. Bei mir kommt bei folgendem Code 6 für x und 123 für i raus:
#include <string> #include <stringstream> using namespace std; int main() { stringstream ss( "123abc" ); int i; ss >> i; unsigned int x = ss.str().length(); }
-
Ich weiß nicht, warum es immer ein stringstream sein muss:
std::string numberOrNot; // ... char *endptr = 0; long number = std::strtol(numberOrNot.c_str(), &endptr, 0); if(*endptr) std::cout << "Nicht als Zahl auswertbar: " << endptr << std::endl;Das ist um Größenordnungen schneller als stringstream, und endptr zeigt am Ende genau auf den Teil des Strings, der nicht als Zahl auswertbar ist. Find' ich am wenigsten umständlich...
Stefan.
-
Danke für den Vorschlag, aber der Vorteil von stringstream ist, dass ich alles mit einer template Funktion erschlagen kann:
template<typename T> T parse_token( const std::string& Token ) { std::stringstream ss( Token ); T value; ss >> value; if( false == ss.eof() ) { throw std::invalid_argument( "Conversion error" ); } return value; }Damit brauche ich für int/double/bool nur eine Funktion statt drei. Die Ausführungsgeschwindigkeit ist nicht wichtig, da ich nur ein Mal beim Programmstart die Kommandozeile parsen muss, da kann der Benutzer ruhig mal ein paar Nanosekunden warten. boost::program_options kann mein Compiler leider nicht.
-
klingt gut, und wie benutze ich das?
double dnum = parse_token ( "3E-1" );error C2783: "T parse_token(std::string &)": template-Argument für "T" konnte nicht hergeleitet werden.
1> ...main.cpp(7): Siehe Deklaration von 'parse_token'
-
double dnum = parse_token<double> ( "3E-1" );
-
Ich mache das sehr ähnlich für einfache ini Files.