Frage zu Aufgabe



  • hallo,
    habe noch eine Aufgabe:
    ich soll ein programm schreiben, dass natürliche Zahlen als Text ausgibt. Einmal vorwärts und einmal rückwärts.

    BSP: 124 -> "eins-zwei-vier" und "vier-zwei-eins".

    Jemand ne Idee wie das gehen könnte?



  • Erstmal musst du es schaffen an die einzelnen Stellen/Ziffern der Zahl zu kommen.
    Das geht mit / und %

    Wenn du die hast kannst du mit einem 2D-char-Array (in dem die Wörter stehen) oder einem switch-case oder einer if-else-Kette die Wörter ausgeben.


  • Mod

    Zwei Vorschläge:
    0. Für beide: Eine Funktion schreiben, die eine Ziffer entgegen nimmt und dann entsprechend "eins" für '1' und "zwei" für '2' usw. ausgibt.
    Damit:
    1. sprintf um eine Zeichenkettendarstellung zu erzeugen. Dann einmal vorwärts und einmal rückwärts mit der Ausgabefunktion (0.) ausgeben.
    2. Mal überlegen, wie man die Ziffern einer Zahl bekommt (Stichwort: Ziffernsystem). Damit eine Funktion schreiben, die einem die Ziffern liefert. Einmal vorwärts und einmal rückwärts ausgeben. Ist quasi das gleiche was sprintf macht, aber man lernt mehr.



  • DirkB schrieb:

    Erstmal musst du es schaffen an die einzelnen Stellen/Ziffern der Zahl zu kommen.
    Das geht mit / und %

    Wenn du die hast kannst du mit einem 2D-char-Array (in dem die Wörter stehen) oder einem switch-case oder einer if-else-Kette die Wörter ausgeben.

    ich weiß schon, was / und % bedeuten, jedoch sehe ich keinen zusammenhang wie ich da an die Stellen/Ziffern kommen soll???



  • Dann rechne doch mal (als int)
    124 % 10 =
    und
    124 / 10 =

    Was fällt dir auf?



  • DirkB schrieb:

    Dann rechne doch mal (als int)
    124 % 10 =
    und
    124 / 10 =

    Was fällt dir auf?

    124 % 10 = 12 R 4
    und
    124 / 10 = 12,4 bei int 12

    und nun?
    also ich steht gerade irgendwie auf dem schlauch!!


  • Mod

    vfbf4n1893 schrieb:

    und nun?
    also ich steht gerade irgendwie auf dem schlauch!!

    Jetzt hast du einmal das Ergebnis 12 und einmal das Ergebnis 4 aus der Zahl 124 geholt. Fällt dir da wirklich nichts auf?

    Was ist denn 12/10 und 12%10?



  • SeppJ schrieb:

    vfbf4n1893 schrieb:

    und nun?
    also ich steht gerade irgendwie auf dem schlauch!!

    Jetzt hast du einmal das Ergebnis 12 und einmal das Ergebnis 4 aus der Zahl 124 geholt. Fällt dir da wirklich nichts auf?

    Was ist denn 12/10 und 12%10?

    ok gut, so komm ich auf die einzelnen zahlen von z.B. 124. Aber was ist wenn die Eingabe variabel ist? Also der Benutzer kann ja auch z.B. 10569 eingeben. Wie bekomme ich das in eine Schleife rein?

    ICh denke ich soll es in einer Schleife darstellen, da wir das gerade durchnehmen.


  • Mod

    Dann rechne mal 10569/10 und 10569%10. Dann nimm das Ergebnis von 10569/10 (nennen wir es 1056 😉 ) und rechne 1056/10 und 1056%10. Dann nimm das Ergebnis von 1056/10 (nennen wir es 105) und rechne 105/10 und 105%10. Den Rest kannst du dir sicher denken.

    War das wohl wichtig, dass ich hier wusste, dass die Zahl 10569 ist oder hätte das auch mit jeder anderen Zahl geklappt?

    edit: Die "Schwierigkeit" ist zu wissen wann man aufhört. Da das aber nicht so schwierig ist, sage ich dir nicht direkt die Lösung, sondern lasse dich erst einmal selber überlegen.



  • #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    char const* digit2word( int unsigned digit, size_t *length )
    {
        static char const *word[ ] =
        { "null", "eins", "zwei", "drei", "vier",
          "f\x81nf", "sechs", "sieben", "acht", "neun" };
    
        static size_t const word_length[ ] =
        { 4, 4, 4, 4, 4, 4, 5, 6, 4, 4 };
    
        return digit < 10 ?
            ( ( *length = word_length[ digit ] ), word[ digit ] )
        :   ( ( *length = 0 ), NULL );
    }
    
    size_t count_digits( int unsigned number )
    {
        int digits = 0;
    
        if( !number ) return 1;
    
        while( number ) {
    
            number /= 10;
            digits++;
        }
    
        return digits;
    }
    
    size_t number2string( int unsigned number, char *dst, size_t max_length, int reverse )
    {
        size_t digits = count_digits( number );
        size_t word_length = 0;
        char **tmp_dst = malloc( digits * sizeof( char* ) );
        size_t length_required = 0;
        size_t i = 0;
    
        for( ; i < digits; ++i ) {
    
            tmp_dst[ i ] = digit2word( number % 10, &word_length );
            length_required += word_length + 1;
            number /= 10;
        }
    
        if( max_length < ++length_required ) {
    
            free( tmp_dst );
            return length_required;
        }
    
        *dst = 0;
    
        if( reverse ) {
    
            for( i = 0; i < digits ; ++i )
            {
                strcat( dst, tmp_dst[ i ] );
    
                if( i + 1 < digits )
                    strcat( dst, "-" );
            }
    
        } else {
    
            for( i = digits; i > 0; --i )
            {
                strcat( dst, tmp_dst[ i - 1 ] );
    
                if( i > 1 )
                    strcat( dst, "-" );
            }
        }
    
        free( tmp_dst );
    
        return length_required;
    }
    
    int main( void )
    {
        unsigned number = 0;
        char out[ 100 ];
    
        number2string( 123456789, &out, 100, 0 );
        printf( "%s\n", out );
    
        number2string( 123456789, &out, 100, 1 );
        printf( "%s\n", out );
    }
    


  • Sehr gut. So lernt er (oder sie) gar nichts.



  • @vfbf4n1893
    Der Code von swordfish schreibt den Text in eine Zeichenkette. Dadurch ist der etwas aufwändiger.

    Das ist aber nicht gefordert. Du kannst die Wörter gleich auf den Bildschirm ausgeben.



  • es geht hier glaube ich nichtmal drum, dass er alle natürlichen zahlen ausgeben kann, sondern nur eine natürlich zahl, also z.b. 124.
    ich kommme aber nicht drauf, wie ich das mit einer schleife ausgeben soll...


  • Mod

    Du hast eine Komplettlösung, die fast ganz genau auf dein Problem passt und mehrere Anleitungen, die den Rechenweg Schritt für Schritt erklären. Was willst du denn noch, außer dass dir wirklich jemand 1:1 die Lösung für genau deine Aufgabe gibt?



  • vfbf4n1893 schrieb:

    es geht hier glaube ich nichtmal drum, dass er alle natürlichen zahlen ausgeben kann, sondern nur eine natürlich zahl, also z.b. 124.

    Achso, das ist einfach:

    puts("eins-zwei-vier");
    

    😃
    Also doch alle.

    vfbf4n1893 schrieb:

    ich kommme aber nicht drauf, wie ich das mit einer schleife ausgeben soll...

    Fehlt dir das Abbruchkriterium, oder wo hakt es.

    ...
    int i, zahl = 124;
    for (i=0;i<8;++i)  // die 8 ist willkürlich gewählt.
    { printf("Zahl: %d | / 10 = %d | %% 10 = %d", zahl, zahl / 10, zahl % 10);
      zahl = zahl / 10;
    }
    ...
    

    Was fällt dir auf? Wann meinst du bist du mit der Schleife fertig?
    (Du musst da aber schon mal compilieren und ausführen, sonst siehst du es nicht)



  • int main()
    {
      /* notwendige konstante Daten, hier 10 Strings (als Literal) */
      char *word[] = {"null","eins","zwei","drei","vier","fuenf","sechs","sieben","acht","neun"};
      unsigned long zahl = 47110815; /* Beispielzahl zum Test */
    
      {
        char str[100],*c=str;
        /* Zahl in String umwandeln, der lässt sich leichter durchlaufen */
        sprintf(str,"%lu",zahl);
    
        while( *c!='\0' ) /* zeichenweise durch den String laufen, und das Ziffernzeichen als Index im o.g. Stringarray gebrauchen */
          puts(word[*c++ -'0']);
      }
    
      return 0;
    }
    


  • DirkB schrieb:

    vfbf4n1893 schrieb:

    es geht hier glaube ich nichtmal drum, dass er alle natürlichen zahlen ausgeben kann, sondern nur eine natürlich zahl, also z.b. 124.

    Achso, das ist einfach:

    puts("eins-zwei-vier");
    

    😃
    Also doch alle.

    vfbf4n1893 schrieb:

    ich kommme aber nicht drauf, wie ich das mit einer schleife ausgeben soll...

    Fehlt dir das Abbruchkriterium, oder wo hakt es.

    ...
    int i, zahl = 124;
    for (i=0;i<8;++i)  // die 8 ist willkürlich gewählt.
    { printf("Zahl: %d | / 10 = %d | %% 10 = %d", zahl, zahl / 10, zahl % 10);
      zahl = zahl / 10;
    }
    ...
    

    Was fällt dir auf? Wann meinst du bist du mit der Schleife fertig?
    (Du musst da aber schon mal compilieren und ausführen, sonst siehst du es nicht)

    diese schleife ist fertig wenn i=8

    ich weiß nicht wie ich die einzelnen ziffern in jeder schleife deklarieren muss. also z.B. wenn ich 124 / 10 = ??? und dann 124 mod 10 = ???

    beim nächsten durchlauf der schlaufe muss ja dann 124 durch das ergebnis der 1. schlaufe ersetzt werden. wie bekomme ich das hin?



  • Wutz schrieb:

    puts(word[*c++ -'0']);  
    }
    

    Da wird das aber untereinander ausgegeben.



  • vfbf4n1893 schrieb:

    diese schleife ist fertig wenn i=8

    Eigentlich ist die Berechnung fertig, wenn sich das Ergebnis nicht mehr ändert.

    vfbf4n1893 schrieb:

    ich weiß nicht wie ich die einzelnen ziffern in jeder schleife deklarieren muss. also z.B. wenn ich 124 / 10 = ??? und dann 124 mod 10 = ???

    beim nächsten durchlauf der schlaufe muss ja dann 124 durch das ergebnis der 1. schlaufe ersetzt werden. wie bekomme ich das hin?

    Steht doch da:

    zahl = zahl / 10;
    

  • Mod

    vfbf4n1893 schrieb:

    beim nächsten durchlauf der schlaufe muss ja dann 124 durch das ergebnis der 1. schlaufe ersetzt werden. wie bekomme ich das hin?

    Du benutzt eine Variable, die sich das Ergebnis merkt.


Log in to reply