Stringauswertung



  • Klar, du musst auch Platz in dem Array definieren.
    In read_number hast du das doch auch bei str_dbl so gemacht.
    Aber das sagt dir doch der Compiler. Evtl. mit Warnungen.

    Zudem ist gets böse, da es solange liest bis die Entertaste gedrückt wird.
    Egal wieviel Speicher da ist.
    Nimm fgets und stdin als Stream.



  • Auch wenn du diese Sachen ändern würdest: Du hast da noch Fehler! Und zwar entspricht das nicht deinen Beispielen... Nach dem Komma darf kein break erfolgen...



  • Danke!

    Ich habe jetzt versucht den Dezimaltrenner selbst zu definieren, aber mit dem code kommt immer 0 raus 😕

    Außerdem hat koschor recht. Nach dem ersten Dezimaltrenner soll die Zahl nicht ganz verworfen werden, sondern die Nachkommastellen ausgewertet werden. Es sei denn das Komms steht im Exponenten.

    Wie in Beispiel: -0,..0,1e-10,1."als -0,01·10^−10

    #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    
    double read_number(char str[], char deztrenner){ 
    
        char str_dbl[80]; 
        size_t i,j; 
        char minus; 
        double dbl; 
    
        for (minus = 1, i = j = 0; i < strlen(str); ++i) 
        { 
            if (str[i] == deztrenner) break; 
            if ( 
                (str[i] == '-' && minus) 
                || (str[i] >= '0' && str[i] <= '9') 
                || (str[i] == 'e' || str[i] == 'E') 
                ) 
            { 
                str_dbl[j++] = str[i]; 
                minus = 0; 
            } 
        } 
        str_dbl[j] = '\0';       
    
        dbl = strtod (str_dbl,NULL); 
    
        return dbl; 
    
    } 
    
    int main( void ) 
    { 
        char str[100];  
        char deztr;
    
        printf("Bitte Zahl eingeben:"); 
        fgets(str,100,stdin);
        printf("Bitte Dezimaltrenner eingeben:");
        scanf("%s",&deztr);
    
        printf ("dbl:     %.f\n",read_number(str,deztr)); 
    
        return 0; 
    }
    

    Wie kann ich das verbessern?



  • Ich weiß zwar nicht was für Werte du eingibst, aber

    - du brichst durch das break die Umwandlung ab. Da gehört ein continue hin

    - musst du auch den Tezimaltrenner ändern in '.', sonst bringt das nichts

    - bei der Ausgabe ist nur der . beim %f etwas blöd. Mach den mal weg.

    - %s bei scanf ist zum einlesen von Nullterminierten Zeichenketten gedacht.
    d.h. um ein Zeichen einzulesen brauchts du Platz für zwei. Dafür reicht deine Variable aber nicht.
    Such dir den Formatspecifier für Charakter.

    Lass dir zwischendurch mal die Werte ausgeben. Am Anfang von read_number und vor strtod.
    Dann kannst du sehen ob die Wandlung überhaupt erfolgreich war.
    Oder nimm den Debugger.



  • Danke Dirk!

    So ich hab das jetzt so modifiziert, wie du gesagt hast.

    #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    
    double read_number(char str[], char deztrenner){ 
    
        char str_dbl[80]; 
        size_t i,j; 
        char minus; 
        double dbl; 
    
        for (minus = 1, i = j = 0; i < strlen(str); ++i) 
        { 
            if (str[i] == deztrenner) continue;
    
            if ( 
                (str[i] == '-' && minus) 
                || (str[i] >= '0' && str[i] <= '9') 
                || (str[i] == 'e' || str[i] == 'E') 
                ) 
            { 
                str_dbl[j++] = str[i]; 
                minus = 0; 
            } 
        } 
        str_dbl[j] = '\0';       
    
        dbl = strtod (str_dbl,NULL); 
    
        return dbl; 
    
    } 
    
    int main( void ) 
    { 
        char str[100];  
        char deztr;
    
        printf("Bitte Zahl eingeben:"); 
        fgets(str,100,stdin);
        printf("Bitte Dezimaltrenner eingeben:");
        deztr=getchar();
    
        printf ("dbl:     %f\n",read_number(str,deztr)); 
    
        return 0; 
    }
    

    Das Problem ist jetzt aber, dass durch das continue der Dezimaltrenner nicht greift. Man muss die ganze Bedingung ändern oder?



  • DirkB schrieb:

    - musst du auch den Dezimaltrenner ändern in '.', sonst bringt das nichts

    Damit meinte ich, dass du an der Stelle wo der Dezimaltrenner steht ein '.' hinschreiben musst.
    Die Bedingung musst du nicht ändern, nur das continue alleine reicht nicht.



  • OK, nächster Versuch 😃

    #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    
    double read_number(char str[], char deztrenner){ 
    
        char str_dbl[80]; 
        size_t i,j; 
        char minus; 
        double dbl; 
    
        for (minus = 1, i = j = 0; i < strlen(str); ++i) 
        { 
            if (str[i] == '.') continue; 
    
            if (str[i]==deztrenner) {
    
                /*...*/
    
            }
    
            if ( 
                (str[i] == '-' && minus) 
                || (str[i] >= '0' && str[i] <= '9') 
                || (str[i] == 'e' || str[i] == 'E') 
                ) 
            { 
                str_dbl[j++] = str[i]; 
                minus = 0; 
            } 
        } 
        str_dbl[j] = '\0';       
    
        dbl = strtod (str_dbl,NULL); 
    
        return dbl; 
    
    } 
    
    int main( void ) 
    { 
        char str[100];   
        char deztr; 
    
        printf("Bitte Zahl eingeben:"); 
        fgets(str,100,stdin); 
        printf("Bitte Dezimaltrenner eingeben:"); 
        deztr=getchar(); 
    
        printf ("dbl:     %f\n",read_number(str,deztr)); 
    
        return 0; 
    }
    

    Ich stelle es mir jetzt in etwa so vor, aber ich komme bei der Bedingung für den Dezimaltrenner nicht weiter 😞

    Wie kann man das lösen?



  • Wenn du das Dezimaltrennzeichen gefunden hast, musst du dieses Zeichen durch einen '.' ersetzen.

    Wenn an der Stelle str[i] dein deztrenner ist, musst du nicht das Zeichen kopieren (wie in Zeile 29: str_dbl[j++] = str[i]; )
    sondern den '.' reinschreiben.

    Nochmal:
    Wenn du str_dbl[j++] = str[i] schreibst, kopierst du das Zeichen an der Stelle i. Das ist jetzt aber dein deztrenner. Stattdessen willst du da einen '.' haben.

    Was ist zu tun?



  • #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    
    double read_number(char str[], char deztrenner){ 
    
        char str_dbl[80]; 
        size_t i,j; 
        char minus; 
        double dbl; 
    
        for (minus = 1, i = j = 0; i < strlen(str); ++i) 
        { 
            if (str[i] == '.') continue; 
    
            if (str[i]==deztrenner) { 
    
                deztrenner = '.';
    
            } 
    
            if ( 
                (str[i] == '-' && minus) 
                || (str[i] >= '0' && str[i] <= '9') 
                || (str[i] == 'e' || str[i] == 'E') 
                ) 
            { 
                if (str[i] != deztrenner){
                str_dbl[j++] = str[i]; 
                    minus = 0; }
    
            /*Hier noch was?*/
    
            } 
        } 
        str_dbl[j] = '\0';       
    
        dbl = strtod (str_dbl,NULL); 
    
        return dbl; 
    
    } 
    
    int main( void ) 
    { 
        char str[100];  
        char deztr;
    
        printf("Bitte Zahl eingeben:"); 
        fgets(str,100,stdin);
        printf("Bitte Dezimaltrenner eingeben:");
        deztr=getchar();
    
        printf ("dbl:     %f\n",read_number(str,deztr)); 
    
        return 0; 
    }
    

    Kann ich jetzt alles außer der Zeile 33 so lassen?



  • MarvC schrieb:

    Kann ich jetzt alles außer der Zeile 33 so lassen?

    Nein, denn so funktioniert das ja nicht.

    Zum testen darfst du auch festen Text im Programm nehmen:

    printf ("dbl:     %f\n",read_number("123,456",','));
    printf ("dbl:     %f\n",read_number("1.23,45.6",','));
    printf ("dbl:     %f\n",read_number("123:456",':'));
    

    (Am besten in Zeile 57)
    Dann siehst du gleich ganz schnell ob es funktioniert.

    In Zeile 19 änderst du nicht das Zeichen im String. Schau dir nochmal Zeile 30 an.
    Da wird das Zeichen kopiert.
    Nur du willst nicht kopieren sondern ein anderes reinschreiben.



  • DirkB schrieb:

    In Zeile 19 änderst du nicht das Zeichen im String. Schau dir nochmal Zeile 30 an.

    for (minus = 1, i = j = 0; i < strlen(str); ++i) 
        { 
            if (str[i] == '.') continue; 
    
            if (str[i]==deztrenner) { 
    
                str[i] = '.';
    
            }
    

    so besser?

    DirkB schrieb:

    Da wird das Zeichen kopiert.
    Nur du willst nicht kopieren sondern ein anderes reinschreiben.

    Wie kann man ein Zeichen in einen festgesetzten Array einschieben?



  • str_dbl[j++] = '.';
    

Anmelden zum Antworten