Buchstaben im String zählen....



  • Hallo zusammen,
    muss für mein Informatikpraktikum einen Code schreiben... Man soll einen Text eingeben können, das Programm soll nicht zwischen Groß- und Kleinbuchstaben unterscheiden.
    Das Programm soll dann zählen, welche Buchstaben wie oft vorkommen und nachher den prozentualen Anteil berechnen.

    Nun beim zählen scheitert es da irgendwo. Weiß aber nicht genau was falsch ist. Manche Buchstaben zählt er richtig, manche ein bisschen falsch und manche brutal daneben. Und je größer man den String definiert, desto größer wird der Fehler (wenn der string nur 10 Zeichen haben soll spinnen soweit ich gesehen habe nur zwei Buchstaben).

    Das ganze wurde gebastelt im QT Creator. Laufend in einer auf Lubuntu basierten virtuellen Maschine, die für diese Zwecke von meiner Hochschule herausgegeben wird.
    Ich hänge hier mal meinen Code an, weiß jemand weiter?

    #include <stdio.h>
    #include <ctype.h>
    #//define max 100
    int main(void)
    {
        int i; //Laufvariable
        int max=1000; // länge des Strings
        char index='a';  //Variable um Buchstaben zu Vergleichen
        int alphabet[26]; //hier werden die gezählten Buchstaben gespeichert
        int j; //Laufvariable
    
        //------String einlesen------
        char eingabe[max];
        printf("Text eingeben\n");
        fgets(eingabe, max, stdin);
        printf("%s\n", eingabe);
    
        for (i=0; i<=max; i++) //Umwandlung von Groß- in Kleinbuchstaben
        {
           eingabe[i]=tolower(eingabe[i]);
    
        }
        printf("%s\n", eingabe); //nochmal in Kleinbuchstaben ausgeben
    
        for (j=0; j<26; j++) //Schleife, zum durchgehen des Alphabets
        {
            for (i=0; i<=max; i++) //Schleife, um alle Buchstaben des Strings durchzugehen
            {
                if( eingabe[i]==index)
                {
                    alphabet[j]++;  //Wenn die Ziffer im String gleich dem aktuellen Buchstabe, zähler erhöhen
                }
            }
            index++; //wechsel auf nächsten Buchstaben
        }
    
      /*  for (j=0; j<=max; j++)
        {
            for (j=0; j<26; j++)
            {
                if (eingabe[j]==index)
                {
                   alphabet[j]++;
                }
                index++;
            }
        }
        */
    
    //----Ausgabe, wie oft jeder Bucshtabe gezählt wurde.
    index='a';
    for (i=0; i<26; i++)
        {
            printf("%c %i\n",index, alphabet[i]);
            index++;
        }
    }
    

  • Mod

    alphabet wird uninitialisiert benutzt.

    Du gehst auch das gesamte Feld durch, egal wie lang die eigentliche Zeichenkette überhaupt ist.

    Deine Indizes laufen falsch. Ein Array mit 1000 Elementen hat gültige Indizes 0 bis 999.

    Dein Programm ist irgendwie ein bisschen schizophren: Einerseits machst du viele Umstände, um nicht von der (falschen) Voraussetzung auszugehen, dass alle Buchstaben des Alphabets in der Zeichentabelle aufeinander folgen. Andererseits geht dein umständlicher Workaround aber von genau dieser (falschen) Voraussetzung aus (Zeile 44).

    Insgesamt gehst du sehr oft die gesamte Zeichenkette durch, 27 mal, was bei langen Zeichenketten dauern kann. Man könnte alles was du tust in einem Rutsch machen. Das würde auch das gesamte Programm wesentlich verkürzen und vereinfachen.



  • Wenn ich mir die Ascii Tabelle ansehe kommen sehrwohl alle Buchstaben nacheinander.... Sonderzeichen müssen nicht berücksichtigt werden.

    Mit der Länge der Zeichenkette hab ich jetzt endlich ne Funktion entdeckt, mit der kann ich die Anzahl der Durchläufe dann deutlich reduzieren...
    Aber ansonsten weiß ich immer noch nicht, wo genau jetzt der Fehler liegt oder wie ich das Programm sonst verkleinern/verbessern könnte. Ich habe da leider nicht die Erfahrung die du hast und die Gesamte Syntax von C hab ich auch nicht im Schädel, damit ginge es wahrscheinlich einfacher...

    Habe bei allen Stellen, die <=max vergleichen jetzt <max eingefügt, dann kommt das wieder hin. Geändert hat sich dadurch aber noch nichts.


  • Mod

    Sesselmann schrieb:

    Wenn ich mir die Ascii Tabelle ansehe kommen sehrwohl alle Buchstaben nacheinander.... Sonderzeichen müssen nicht berücksichtigt werden.

    Und dein Computer nutzt garantiert ASCII?

    Mit der Länge der Zeichenkette hab ich jetzt endlich ne Funktion entdeckt, mit der kann ich die Anzahl der Durchläufe dann deutlich reduzieren...

    Du wirst sicherlich immer noch sämtliche Werte uninitialisiert benutzen, da du nichts davon schreibst, dass du diesen Fehler berichtigt hättest.

    Wie machst du es denn nun mit der Länge? Doch wohl hoffentlich nicht

    for (int i = 0; i < strlen(zeichenkette); ++i) ...
    

    ? Das wäre noch viel schlimmer. Eigentlich brauchst du überhaupt keine fertigen Funktionen, geh einfach von vorne nach hinten durch, bis du bei '\0' ankommst.



  • SeppJ schrieb:

    alphabet wird uninitialisiert benutzt.

    Falls du nicht weißt, was das bedeutet, dann kopiere die Ausgabe (Zeile 63-67) mal hinter mal hinter Zeile 29 (//nochmal in Kleinbuchstaben ausgeben)

    SeppJ schrieb:

    Und dein Computer nutzt garantiert ASCII?

    Für den Anfang kann man mal davon ausgehen.
    Wenn er das Prinzip verstanden hat, kann er ja auf Nicht-ASCII gehen.



  • Ja das mit dem alphabetg ist jetzt gefixt... jetzt weiß ich was gefehlt hat. Mit der Funktion meine ich strlen. Kann sein, dass ich die falsch verstehe, aber das muss ich noch ausprobieren....
    Ich kenn mich noch nicht wirklich aus, bitte nicht hauen 😕

    Hier auch wieder: Keine Ahnung was du meinst, und was ich da beachten sollte, aber eins steht fest, wenn ich meine Ausgabeschleife laufen lasse, stehen links alle Buchstaben von a-z ohne Lücken, anderen Zeichen, doppelten Zeichen oder ähnlichem. Das bedeutet also auch, dass der Code oben auch von a-z abfragt. Das reicht mir jedenfalls aus....



  • Das mit dem strlen war wohl des Rätsels Lösung.

    Habe bei allen Schleifen, die vorher das max verwendet haben, einfach die Stringlänge reingeschmissen und jetzt tut er was er soll...



  • Weißt du, wie ein C-String aufgebaut ist?



  • Muß der Text in Kleinbuchstaben ausgegeben werden? - Ist die Aufgabenstellung so? Wenn nicht, dann könntest Du eine Schleife sparen.



  • In einem Rutsch (natürlich nicht Alles):

    char *p = eingabe;
    int chcnt = 0;
    for( ; *p; chcnt += isalpha( *p++ ) ? 1 : 0 );
    printf( "chcnt: %d\n", chcnt );
    

  • Mod

    EOP schrieb:

    In einem Rutsch (natürlich nicht Alles):

    char *p = eingabe;
    int chcnt = 0;
    for( ; *p; chcnt += isalpha( *p++ ) ? 1 : 0 );
    printf( "chcnt: %d\n", chcnt );
    

    Ich glaube, du hast die Aufgabe nicht richtig verstanden:

    Sesselmann schrieb:

    Das Programm soll dann zählen, welche Buchstaben wie oft vorkommen



  • SeppJ schrieb:

    Ich glaube, du hast die Aufgabe nicht richtig verstanden:...

    Ich glaube, du hast nicht richtig gelesen.

    natürlich nicht Alles

    Ich habe nur erstmal die Buchstaben gezählt, um ihm zu zeigen wie man es macht. Bin ja nicht der Hausaufgabendoktor wie Herr Muemmel.


Log in to reply