string auf zahl ueberpruefen



  • Danke,
    aber - naja ich wollte schon eher ne C++ Loesung mit vielleicht was fuer strings.

    Ich weiss das es da eine Funktion isDigit() oder so aehnlich gibt, mit der man das, glaube ich, in C fuer char[] macht... habe aber auch keine Ahnung wie ich die hernehme (das sie auch sicher ist).

    Gibts da nix elegantes fuer C++ ???



  • Du kannst es ja mal hiermit versuchen.

    // Funktion strToD() - konvertiert Zahlen aus einem String zu einem double Datentyp. 
            // Argumente: String vom Typ string, welcher die zu konvertierenden Zahlen enthaelt. 
            // Return Wert: 0.0 wenn Konverterungsfehler, ansonsten konvertierte Zahl vom Typ double.
            // Anmerkung:
            //              Die Funktion strToD() benoetigt die Funktion multiplicate() um die Nachkomma-
            //              stellen zu berechnen.
    
            int multiplicate(const int);        // Prototyp
    
            double strToD(const std::string& str)
            {
                    unsigned int i;
                    bool negative = false;
                    double number = 0.0;
    
                    for(i = 0; i < str.length() && std::isspace(str[i]); i++)
                            ;
    
                    if(str[i] == '-')
                    {
                            negative = true;
                            ++i;
                    }
    
                    for(unsigned int j = i; j < str.length(); ++j)
                            if(!std::isdigit(str[j]) && str[j] != '.')
                                    return 0;
    
                    for( ; str[i] != '.' && i < str.length(); ++i)
                            number = number * 10 + (str[i] - '0');
    
                    if(str[i] == '.')
                    {
                            ++i;
                            double afterPoint = 0.0;
                            for(int count = 1 ; i < str.length(); ++i, ++count)
                                    afterPoint = afterPoint + ((str[i] - '0') / (double)multiplicate(count));
    
                            number += afterPoint;                                
                    }
                    if(negative)
                            return (number * (-1));
                    else
                            return number;
            }
    
            // Unterfunktion der Funktion strToD(). Wird benoetigt, um die Nachkommastellen zu berechnen.
            int multiplicate(const int l)
            {
                    int j = 1;
                    int factor = 10;
                    while(j++ < l)
                            factor *= 10;
    
                    return factor;
            }
    

    Hoffe ich konnte helfen. (Kann sein, dass sich hier ein paar Fehler(chen) eingeschlichen haben, da ich hundemüde bin) 🙂

    Caipi



  • Hallo,

    einfacher gehts mit Stringstreams:

    #include <iostream>
    #include <sstream>
    #include <string>
    using namespace std;
    
    int main()
    {
            double zahl;
            string test("Test");
            stringstream puffer;
    
            puffer << test;
    
            if(!(puffer >> zahl))
                    cout << "String war kein Double" << endl;
            else
                    cout << zahl+1 << endl;
    }
    


  • @CartenJ
    Warum einfach wenns auch kompliziert geht 😉
    Das kommt davon, wenn man erst die (absoluten) Grundlagen von C++ beherscht 😞

    Die Klasse stringstream scheint richtig interessant zu sein, ich glaube ich muss mich in der nächsten Zeit mal mit ihr beschäftigen...

    Caipi



  • Caipi schrieb:

    @CartenJ
    Warum einfach wenns auch kompliziert geht 😉
    Das kommt davon, wenn man erst die (absoluten) Grundlagen von C++ beherscht 😞

    Die Klasse stringstream scheint richtig interessant zu sein, ich glaube ich muss mich in der nächsten Zeit mal mit ihr beschäftigen...

    Mit einem Blick in die FAQ hättest du das selbst rausfinden können. 😉



  • Hallo, nix fuer ungut Jungs, aber bis auf Enno-hydrant ist noch niemand auf mein Problemchen eingegangen 🙂 oder besser :xmas1: Danke trotzdem !! vielleicht hab ichs ja falsch erklaert.

    Problem:
    Ich will pruefen ob ein string eine Zahl (wenns geht double) ist oder eben nicht.

    Was ich nicht will:
    Eine Zahl aus einem string auslesen, und wenns nicht hinhaut 0.0 zurueckgeben lassen. Erstens kann ich das schon (selber aus der FAQ finden) und zweitens wuerde das Programm dann keinen Unterschied machen, wenn wirklich 0.0 im string steht oder einfach nur blabla. Ich braeuchte vielleicht eher was was mir nen bool, also ja oder nein zurueckgibt.
    Ach ja double deshalb, weil ich dann auch Kommazahlen als Zahl erkennen lassen koennte.
    Anderer Ansatz, ich habe mir ueberlegt, das es evtl auch ausreichen wuerde (fuer meine Zwecke) den string in nen c_str umzuwandeln und dann das erste Zeichen mit isdigit() zu pruefen ob es eine Zahl (dann int) is oder nicht. Aber ich kenne die Funktion isdigit eben nur vom hoeren-sagen von C.

    Fragen:
    Wie benutzt isdigit() aus C ?
    Gibt es eine vergleichbare (bessere) Funktion wie isdigit() in C++ ?
    Wie benutzt man die vergleichbare (bessere) Funktion wie isdigit() in C++ ?



  • Hi!

    Hä? Das macht doch der Code von CarstenJ. Er versucht zwar die Zahl umzuwandeln, aber im Endeffekt prüft er nur ob es sich um eine Zahl handelt oder nicht und seine Methode ist die wohl in C++ angenehmste, als jedes Zeichen mit der Funktion isdigit() zu vergleichen und auch noch zu prüfen das max. ein '.' im String enthalten ist.
    Wozu das Rad neu erfinden? Die Funktion isdigit liefert doch alles was man braucht. Du übergibst ein Zeichenwert und bekommst einen int zurück der einen Wert ungleich 0 zurückgibt wenn das Zeichen eine Zahl ist.

    Code-Hacker



  • Wie wärs damit? Einfache Prüfung, ausbaubar...

    bool is_fltpnt(const string& s)
    {
        string::const_iterator i=s.begin();    //Geht das? - aufgrund von Ben04s Vorschlag ein const_iterator, erscheint mir auch logischer
        if(*i=='-'||*i=='+')                   //evtl. Vorzeichen übergehen
            ++i;
        string::const_iterator end=s.end();
        bool comma=false;                      //ist ein Komma gefunden worden?
        for(;i!=end;++i)                       //alle Zeichen überpr.
        {
            if((*i==','||*i=='.')&&!comma)     //erstes Komma gefunden
                comma=true;                    //vermerken
            else if(*i>='0'&&*i<='9');         //tu nix - es handelt sich um eine legale Zahl
            else return false;                 //es ist eintweder keine Zahl oder ein zweites(drittes...) Komma - keine Zahl
        };
        return true;
    };
    


  • wie ? hydrant ??? 😮



  • ness schrieb:

    Wie wärs damit? Einfache Prüfung, ausbaubar...

    bool is_fltpnt(const string& s)
    {
        string::iterator i=s.begin();    //Geht das?
        if(*i=='-'||*i=='+')
            ++i;
        string::iterator end=s.end();
        bool comma=false;
        for(;i!=end;++i)
        {
            if((*i==','||*i=='.')&&!comma)
                comma=true;
            else if(*i>='0'&&*i<='9');   //tu nix
            else return false;
        };
        return true;
    };
    

    Da glaub ich müsstest du ein string::const_iterator nehmen.

    BTW: Kriptischer hast du das nicht hinbekommen wie? 😉

    @enno-tyrant 😃



  • @Wendy:
    Mir ist leider immer noch nicht klar, inwieweit die Stringstreamlösung nicht deinen Anforderungen entspricht.

    Eine Kommazahl kannst du auch mit "locales" überprüfen:

    #include <iostream>
    #include <sstream>
    #include <string>
    #include <locale>
    
    using namespace std;
    
    int main()
    {
            double zahl;
    
            string test("90,2323");
    
            stringstream puffer;
    
            puffer.imbue(locale("de_DE"));
            cout.imbue(locale("de_DE"));
            puffer << test;
    
            if(!(puffer >> zahl))
                    cout << "String war kein Double" << endl;
            else
                    cout << zahl << endl;
    }
    

    Das nun alles in eine Funktion zu schreiben, sollte eigentlich kein Problem sein.



  • @CarstenJ ganz so einfach geht das nicht. Was wäre wenn test = "12,8 abcdefg" wäre? Deine Funktion würde es als Zahl erkennen.



  • @CarstenJ
    tschuldige, die erste Loesung entspricht den Anforderungen.
    Ich habe sie noch nicht getestet ob sie funktioniert oder ob es Ausnahmen gibt, in meinem Anwendungsfall, aber ich denke das es passen muesste, vielen Dank.

    Ich dachte eben zu sehr an eine Funktion als direkt den Sream hernehmen zu koennen und die Umwandlung gleich als "Pruefung" zu benutzen.
    Ist das nicht riskant, ich hatte eigentlich ja vor eben genau diese Funktion zu benutzen um bei der Umwandlung sicherzustellen, dass es sich auch um eine Zahl handelt und der Stream nicht irgendwie einen Fehler hervorruft ?

    @enno-tyrant: war nich so gemeint 😉 darfst mich "sandy" oder so nennen - OK ?
    :xmas2:

    aber ich finde die Problematik nun irgendwie immer interessanter, gibts da keine Standardvorgehensweise, wie etwa StringToDouble (siehe FAQ), das Problem duerfte doch genauso gaengig sein nicht? Was mache ich nun wenn ich eben "123WERT" oder sowas habe? Kann ich das nicht irgendwie auch ueber den stringstream pruefen evtl mit ner Laengenpruefung oder ein stellenweises uebertragen oder ??? oder is das gena das was in der anderen Methode gemacht wird?

    wichtig: ich habe nun, nach einer Weihnachtspause, feststellen muessen, dass die Probe ueber den stringstream bei strings wie etwa "123wert" eine Zahl "123" zurueckgibt und dann abbricht, damit wird bei einer boolabfrage (ich nenn das mit "if else" mal so...) ein true draus, was natuerlich falsch ist. Wie mach ich es nun, dass "123wert" eben als Zeichenfolge und nicht als Zahl erkannt wird ???


Anmelden zum Antworten