Dezimalwert eines numerischen Strings



  • Hey leute meine letzte Frage ist folgende. Danke euch vielmals für eure Hilfe bisher.

    Warum funktioniert mein Programm nicht? Keine Angst ich poste nicht sofort hier los. ich sitze schon min. eine Stunde dran und hab hin und her verändert aber es wird nix drauß 😞

    Also wo ist der Fehler. Ausgabe ist 0.

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    
    int dec(char *s)
    {
        int i;
        double a=0;
        double b=0;
        double c=0;
    
        for(i=0;s[i]!='\0';i++)
        {
    
            a=strlen(s)-2-i;
            b=(s[i])*pow(10,a);
            c=c+b;
    
        }
    
        return c;
    }
    
    int main()
    {
    char s[]="234";
    double d=dec(s);
    printf("dec: %d ", d);
    getchar();
    return 0;
    }
    

    Danke euch! 🙂



  • '2' != 2
    

  • Mod

    Mehrere Fehler:
    1. Du mischt wild doubles in deinen Code ein, obwohl der Rest deines Programms geschrieben ist, als wäre alles int. Dies ist insbesondere sehr falsch bei deiner Ausgabe, da %d der Formatspezifizierer für Integer ist (d für Dezimalformat). Falls du die doubles eingeführt haben solltest, weil sonst der Aufruf von pow nicht funktionierte: Dann benutzt du einen C++-Compiler für C. Benutz einen C-Compiler!
    2. '1' != 1 . Das heißt, das (s[i])*pow(10,a) ganz was anderes ist als der Wert der Ziffer an der Stelle i. Trick: '1' - '0' == 1
    3. a=strlen(s)-2-i; Das ist wild. mal angenommen, wir haben 3 Ziffern (dein "234"), dann ist strlen(s) == 3 (es ist übrigens ganz schlecht, strlen in einer Schleife aufzurufen! strlen ist sehr teuer. Ruf es einmal vor der Schleife auf!). Das heißt bei i == 0 ist a == 3-2-0 == 1 und pow(10,a) == 10. Passt nicht, da die erste Stelle 100 zählt. Den nochmal genauer nach!

    Das Ganze ginge auch viel einfacher, ganz ohne strlen und Potenzieren:
    1.Setze das Gesamtergebnis auf 0.
    2.Gehe zur nächsten Ziffer.
    3.Falls diese existiert (d.h. kein Nullzeichen ist):
    -Multipliziere das Gesamtergebnis mit 10
    -Addiere den Wert der Ziffer zum Gesamtergebnis
    -Zurück zu 2.
    sonst:
    -Fertig.



  • #include <stdio.h>
    #include <string.h>
    #include <math.h>
    
    int dec(char *s)
    {
        int a=0, b;
        int i=0;
        int c=strlen(s);
        while(s[i]!='\0')
        {
            a=s[i]*pow(10,(c-1+i));
            b=b+a;
            i++;
        }
        return b;
    }
    
    int main()
    {
        char s[]="234";
        dec(s);
        printf("dec: %d ", dec(s));
    
        getchar();
        return 0;
    }
    

    ich verstehe zwar den fehler, aber weiß nich wie ich das anwenden soll. vorallem das mit '1'. verstehe das zb nicht.

    und die kürzere variante habe ich auch nicht verstanden. wäre echt super wenn mir jemand nochmal helfen könnte.

    vielen vielen dank.


  • Mod

    Der Wert des Zeichens '2' (die Ziffer) ist nicht gleich 2 (die Zahl)! Das heißt '2' * 5 ist nicht 10, sondern irgendwas ganz anderes. Aber '2' - '0' ist gleich 2, somit ist ('2' - '0') * 5 gleich 10. Ebenso für alle anderen Ziffern.

    Verstanden?



  • erstmal dankeschön.
    muss ich dann a=(s[i]-'0')*(pow(10,c-1-i) schreiben?
    da ja (wenn s[]="234")
    s[0]='2';
    s[1]='3';
    2[2]='4';

    habe das so geändert aber habe das gefühlt hier ist auch noch ein fehler:

    while(s[i]!='\0')
        {
            a=(s[i]-'0')*(pow(10,(c-1-i)));
            b=b+a;
            i++;
        }
        return b;
    


  • CCCstringcast schrieb:

    muss ich dann a=(s[i]-'0')*(pow(10,c-1-i) schreiben?

    Nein, musst du nicht. Es geht effektiver ohne diesen Funktionsaufruf.
    Wie man das macht, dazu hat dir SeppJ schon den Pseudocode geliefert.


  • Mod

    CCCstringcast schrieb:

    habe das so geändert aber habe das gefühlt hier ist auch noch ein fehler:

    while(s[i]!='\0')
        {
            a=(s[i]-'0')*(pow(10,(c-1-i)));
            b=b+a;
            i++;
        }
        return b;
    

    Nein, dein Fehler liegt weiter vorne. Du hast es irgendwie geschafft, den Fehler im ersten "verbesserten" Code einzubauen, obwohl er im Original nicht drin ist. Guck dir den Code nochmal genau an, die Sache ist eigentlich offensichtlich. Zumindest für jemanden mit Erfahrung. Ich verrat's dir absichtlich nicht direkt, damit du auch Erfahrung bekommst.

    Warnt dich dein Compiler eigentlich nicht? Falls nein, dann mach dich mal kundig, wie du Compilerwarnungen einschaltest. Damit findest du den Fehler auch sofort.



  • jaaaaa! ich habs. nach gefühlten 1000 stunden.
    sogar beide versionen haben geklappt 😃 😃

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    
    int dec(char *s)
    {
        int i;
        double b=0;
        double d=strlen(s);
    
        for(i=0;s[i]!='\0';i++)
        {
            b+=(s[i]-'0')*pow(10,d-1-i);
        }
        return b;
    }
    
    int main()
    {
        char s[]="234";
        dec(s);
        printf("dec: %d", dec(s));
        getchar();
        return 0;
    }
    
    #include <stdio.h>
    #include <string.h>
    
    int dec(char *s)
    {
        int i;
        double a=0;
        double b=1;
    
        for(i=strlen(s)-1;i>=0;i--)
        {
            a+=(s[i]-'0')*b;
            b*=10;
        }
        return a;
    }
    
    int main()
    {
        char s[]="234";
        dec(s);
        printf("dec: %d", dec(s));
        getchar();
        return 0;
    }
    

    danke euch vielmals. falls trotzdem noch ein fehler dabei ist. sagt es bitte. danke 🙂


  • Mod

    Wieso mischt du denn nun schon wieder double und int?

    Die "kanonische" Lösung wäre übrigens etwas in dieser Art (Vorzeichen lasse ich mal weg):

    unsigned dec(const char *s)
    {
      unsigned result;
      for(result = 0; *s; result = result * 10 + *s++ - '0');
      return result;
    }
    

    In der Praxis würde man natürlich strtol, sscanf, atoi & Co. benutzen, die dir hoffentlich bekannt sind.



  • Mal übersetzt:

    unsigned b = 0;
        for(i=0; s[i]!='\0'; i++)
        {
            b = b*10 + s[i]-'0' ;
        }
        return b;
    

Anmelden zum Antworten