Buchstabenhäufigkeit, histogramm
-
Hallo, ich habe versucht die Buchstabenhäufigkeit zu programmieren und anschließend die als Histogramm auszugeben. Klappt irgendwie nicht. Wo könnte das Fehler liegen? danke im voraus
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void balkendiagramm( int *zaehler ){
int i,j;
int charCount[26][2];for(i=0;i<26;i++){
printf("%c:",(char)charCount[i][0]);
for(j = 1; j<=charCount[i][1]; j++)
printf("*");
printf("\n");
}}
int main(){
char text[1024];
FILE * datei;
int charCount[26][2];
int i, Inhalt,j;datei=fopen("sample.txt","r");
if(datei!= NULL){
fscanf(datei,"%1024c",text);
text[1024]='\0';fclose(datei);
}
for(i=0,Inhalt='a';Inhalt<='z';i++,Inhalt++)
{
charCount[i][0]=Inhalt;
charCount[i][1]=0;
}
printf("Haefigkeit der Buchstaben:\n");
for(i=0;text[i]!='\0';i++){
for(j=0;j<26;j++){
if(text[i]==charCount[j][0]){
charCount[j][1]++;}
}
}
balkendiagramm(&charCount[26][1]);system("PAUSE");
return 0;
}
-
Du gibst in Zeile 10 und 14 charCount aus obwohl es nicht initialisiert wurde und den Parameter verwendest du nicht. ???
In Zeile 32 und 48 gibt es einen Überlauf. ( text[1024] geht von text[0] bis text[1023].Gib mal eine genauere Fehlerbeschreibung als "klappt nicht" und formatiere den Code ordentlich.
-
Die Fehler liegen irgendwo im Code.
Der Aufruf von balkendiagramm und die PAramter der Funktion passen nicht zusammen.
Auch wenn du den Compiler mit einfügen von Sonderzeichen ruhig gestellt hast.Ohne Code-tags kann man dein Programm sehr schlecht nachvollziehen, da die Einrückungen verloren gehen.
Benutze das eingelesen Zeichen als Index. Aus dem Index ergibt sich auch das Zeichen, so dass du nur ein 1D-Array brauchst.
fscanf
nimmt man zum einlesen von einzelnen Werten oder Wörtern.
Ganze Zeilen liest man mitfgets
ein,
ganze Dateien liest man mitfread
ein.Für einzelne Zeichen nimmt man
fgetc
-
Hallo nara99
Tolle Idee eine Datei mal so aufzuzeigen!
Du könntest da auch jedes Byte einzeln zählen. Vieleicht inspiriert dich
dein von mir nur geringfügig verändertes Prog. Problem ist vorher sollte man
die Fensterbreite kennen, da ja die Häufigkeit richtig dargestellt werden sollte.
Hier dein Prog leicht verändert:#include<stdio.h> #include<string.h> #include<stdlib.h> void balkendiagramm( unsigned char letter[]) { int i, j, erstes, letztes, maximal; maximal = 0; for(i=0; i<= 255; i++) if (letter[i] > maximal) maximal = i; letztes = 0; for(i=255; i >= 0; i--) if (letter[i] != 0 ) { letztes = i; break; } erstes = 0; for(i=0; i <= 255; i++) if (letter[i] != 0 ) { erstes = i; break; } printf("Haeufigster Buchstabe: %c=%d dez\n", maximal, maximal); printf("Erstes autretendes ASCII-Zeichen Nr.: %d\n", erstes); printf("Letztes autretendes ASCII-Zeichen Nr.: %d\n\n", letztes); printf("ASCII Haeufigkeit\n"); for(i = erstes; i<= letztes; i++) { if ((i >= 32) && (i <127)) printf("\n%3d=%c %4d ", i, i, letter[i]); else printf("\n%3d= %4d ", i, letter[i]); for(j=0; j < letter[i]; j++) printf("*"); //printf("\n"); } } int main() { unsigned char letter[256]; char filename[500]; FILE *datei; int i, zeichen; long filelength; printf("Dateistatisitik\n"); printf("Bitte Dateinamen eingeben: "); scanf("%s", filename); datei=fopen(filename, "rb"); if(datei == NULL) { printf("Datei %s konnte nicht geoeffnet werden.\n", filename); return 1; } else { /* vorher Dateilänge mit ftell() feststellen */ fseek(datei, 0L, SEEK_END); filelength = ftell(datei); fseek(datei, 0L, SEEK_SET); printf("Dateilänge von %s: %ld Byte\n\n", filename, filelength); for ( i = 0; i <= 255; i++) letter[i] = 0; for ( i = 0; i < filelength; i++) if((zeichen = fgetc(datei)) != EOF ) letter[zeichen]++; } fclose(datei); printf("\nDatei geschlossen.\n"); balkendiagramm(letter); system("PAUSE"); return 0; }
Experimentierst du etwa mit Dechiffrierung von verschlüsselten Dateien
oder Texten, welche mit Hilfe der Substitution und symmetrischen Verfahren kodiert wurden?
Mit deiner Methode kann man nachweisen, das das "e" in der deutschen Sprache
bei weitem der am häufigsten verwendete Buchstabe ist. Damals wurde das den
deutschen U-Bootfahrern im 2ten Weltkrieg zum Verhängnis. Damals hatten die
in englischen Blechley Park unter der Mithilfe des Mathematikers Alan Turing
entworfenen Rechenmaschinen("Bombs"), deutsche Funksprüche auf die statistische Häufigkeit von Buchstaben
und verwendeten Textpassagen wie "Führerhauptquatier" oder "Oberkommando" getestet und
entschlüsselt. Die Wirkung der Arbeiten der damaligen britischen Geheimorganisation
"Ultra" dürfte hinlänglich bekannt sein.Sorry wegen der kleinen Exkursion in Geschichte, aber ich hatte mich mal für Kurzwellenfunk interessiert. Da lernt
man so etwas.INFO für Anfänger:
die ASCII-Zeichen 0 bis 32 dienten früher als Steuerzeichen für die
Datenübertragung über die damalige serielle Schnittstelle RS232.
Deren damalige Bedeutung:Hier eine Liste der Bedeutung der ASCII-Zeichen von 0 bis 32 als Steuerzeichen für Datenübertragung, Drucker, Bildschirmsteuerzeichen, usw.: 00 NULL, no Operation, ..........NUL keine Operation 01 Start of Heading .............SOH Vorspannanfang 02 Start of Text ................STX Textanfang 03 End of Text ..................ETX Textende 04 End of Transmission ..........EOT Übertragungsende 05 Enquiry ......................ENQ Stationsanruf 06 Acknowledge ..................ACK Bestätigung 07 Bell..........................BEL Klingel 08 Backspace.....................BS Rückwärtsschritt 09 HAT...........................Horizontal Tabulation 10 Line Feed.................... LF Zeilenvorschub 11 Vertical Tabulation VT 12 Form Feed FF..................Formularvorschub, Schirmlöschen 13 Carrige Return ...............CR Wagenrücklauf 14 Shift out ....................SO Umschalten aus 15 Shift in .....................SI Umschalten ein 16 Data Link Escape..............DLE Austritt aus der Datenverbindung 17 Device Control 1..............DC1 Gerätesteuerung 1 18 Device Control 2..............DC2 Gerätesteuerung 2 19 Device Control 3..............DC3 Gerätesteuerung 3 20 Device Control 4..............DC4 Gerätesteuerung 4 21 Negative Acknowledge .........NAK Fehlermeldung 22 Synchronous Idle .............SYN Synchronisierung 23 End of Transm.Block...........ETB Datenblockende 24 Cancel .......................CAN ungültig 25 End of Medium ................EM Datenträgerende 26 Substitute ...................SUB Character Zeichen ersetzen 27 Escape........................ESC Rücksprung 28 File Separator................FS Filetrennung 29 Group Separator...............GS Gruppentrennung 30 Record Separator .............RS Untergruppentrennung 31 Unit Separator ...............US Einheitentrennung 32 Space ........................SP Leerschritt
Wie diese Zeichen heute wichtig sind für Sitor-A, Sitor-B, Navtex,
RTTY, Amtor-Verfahren, und der ITA2 (Baudot code), welche für die
Datenübertragung per Kurzwellenfunk zu Schiffen wichtig sind, entzieht
sich leider meiner Kenntnis.