Frage von Patrick0891, 97

Probleme mit C-Programmierung: Zahlen sortieren?

Hallo, ich habe folgendes Programm geschrieben und komme einfach nicht weiter. Das Programm zählt die Buchstaben einer .txt Datei und gibt ebenso deren Häufigkeit an. Ich soll jetzt noch die Anzahl der Buchstaben beginnen mit der größten Zahl sortieren. Die Buchstaben müssen dabei auch stimmen und natürlich die Häufigkeit. Kann mir jemand dabei helfen?

So weit bin ich gekommen, eine Beispiel txt Datei wurde implementiert. Ich programmiere mit Codeblocks.


#include <stdio.h>

include

char dateiname[40]; int anweisung1;

int main(int argc, char **argv) { if (argc != 2) { printf("Der Dateiname fehlt\n"); return 0; }

FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
    printf("Die Datei kann nicht geoeffnet werden\n");
    return 0;
}

double anzahl[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int gesamt = 0;


while (1) //Zähschleife
{
    int buchstaben = fgetc(fp);
    if (buchstaben < 0)
    {
        break;
    }
    if (buchstaben >= 'A' && buchstaben <= 'Z') //Zählschleife für Großbuchstaben
    {
        anzahl[buchstaben - 'A']++;
        gesamt++;
    }
    else if (buchstaben >= 'a' && buchstaben <= 'z')
    {
        anzahl[buchstaben - 'a']++; //Zähschleife für Kleinbuchstaben
        gesamt++;
    }
}


fclose(fp);

int anweisung;
printf("Dieses Programm zaehlt die die Buchstaben in einer .txt Datei\nund gibt die Haeufigkeit der Buchstaben an\n");
printf("Sie haben jetzt die Auswahl zwischen:\n");
printf("1. Die .txt Datei mit printf in der Konsole auszugeben\n");
printf("2. Eine neue .txt Datei zu speichern\n\n");
scanf("%d", &anweisung);

switch(anweisung)
{
case 1:
    printf("Die Gesamtzahl der Buchstaben lautet: %d\n",gesamt);

    int i;
    for (i = 0; i < 26; i++)
    {
        printf("%c : %0.lf", (i + 'A'), anzahl[i]);
        double prozente = anzahl[i]*100/gesamt;
        printf("\tHaeufigkeit: %.2lf%%\n",prozente);
    }
    return 0;

case 2:

    printf("\nBitte geben Sie den Dateinamen mit .txt an:\n\n");
    scanf("%s", dateiname);
    printf("\nIhre Datei heisst: %s.\n", dateiname);

    FILE* fp;
    fp = fopen(dateiname,"w");
    fprintf(fp,"Die Gesamtzahl der Buchstaben lautet: %d\n",gesamt);

    for (i = 0; i < 26; i++)
    {
        fprintf(fp,"%c : %0.1f\t  ", (i + 'A'), anzahl[i]);
        double prozente = anzahl[i]*100/gesamt;
        fprintf(fp,"Haeufigkeit: %.2lf%%\n",prozente);
    }
    return 0;
    fclose(fp);
}

}

Antwort
von Mikkey, 61

Wenn Du Dich auf 8-Bit-Zeichen beschränkst, kannst Du auch in ein Zähl-Array [256] saldieren:

while (0 < c = fgetc(fp)) zaehlArray[c]++;

Es ist kein guter Stil, ohne Not "while (1)" zu verwenden, wenn man ohnehin die Abbruchbedingung in Reichweite hat.

Nun kannst Du mit direkter Auswahl die Buchstabenanzahlen ab

zaehlArray['A']+zaehlArray['a'] sortieren.

Antwort
von oelbart, 45

Funktioniert das Zählen denn schon? Wenn ja: Such doch mal nach "Bubble Sort" oder "Quicksort". (Wobei bubble bei 26 eingaben vermutlich sogar schneller ist als Quick)

Oder wo ist das Problem noch? 

Zwei kleine Hinweise noch: Deine if-Anweisungen sind KEINE Zählschleifen, da rollen sich manchen Leuten hier die Fußnägel rauf

Und: Wieso  benutzt Du doubles zum zählen?

Kommentar von Patrick0891 ,

Das Programm funktioniert so weit, nur sortiert er die Zahlen noch nicht. Ich probiere es nochmal mit Bubblesort, nur hat das Programm nur Mist ausgespuckt als ich es damit versucht habe. Hab double genommen wegen der Nachkommastellen der Häufigkeit. Mit int Werten kam keine zweite Nachkommastelle.

Ich bin halt kein pro und überhaupt froh, wenn die Programme das machen, was sie sollen. :D

Kommentar von oelbart ,

Mit int hast Du überhaupt keine Nachkommastellen, aber wozu brauchst Du nachkommastellen, wenn Du Buchstaben zählst?

Kommentar von Patrick0891 ,

Ich habe auch die Häufigkeit in % der vorkommenden Buchstaben mit angegeben.

Kommentar von oelbart ,

Jo, im Array "prozente". Aber davor zählst Du doch nur, oder?

Also, nicht dass  das nicht funktioniert, aber es könnte den Leser etwas verwirren, weil er erwartet, dass da noch was mit gemacht wird.

Kommentar von Patrick0891 ,

Frag mich nicht wieso, aber ich hatte das Array vorher als int Wert festgelegt, allerdings hat er für prozente keine Nachommastellen mehr gehabt, wenn ich das Programm dann ausgeführt habe.

Kommentar von oelbart ,

Klar, wenn Du int/int rechnest, benutzt er die Integer-Division und die ist abrundend ("Division ohne Rest")

Das lässt sich aber verhindern, indem Du zb schreibst prozente= (double)anzahl/gesamt
(oder prozente = anzahl/(double)gesamt - musste ausprobieren)

Keine passende Antwort gefunden?

Fragen Sie die Community