Das Programm aus diesem Abschnitt öffnet die angegebene Textdatei und zählt, wie oft die einzelnen Zeichen darin enthalten sind. Es werden alle Standardzeichen der Tastatur, einschließlich Groß- und Kleinbuchstaben, Zahlen, Leerzeichen und Satzzeichen gezählt. Die Ergebnisse werden auf dem Bildschirm ausgegeben. Dieses Programm kann nicht nur richtig nützlich sein, sondern es enthält auch einige sehr interessante Programmiertechniken. Mit dem Umleitungsoperator (>) des Betriebssystems können Sie die Ausgabe in eine Datei umleiten. So wird zum Beispiel mit dem Befehl
zeichen > ergebnisse.txt
das Programm ausgeführt und die Ergebnisse werden in eine Datei namens
ergebnisse.txt
ausgegeben anstatt auf dem Bildschirm angezeigt.
E&A-Listing 4. zeichen.c: ein Programm zum Zählen der Zeichen in einer Datei.
1: /* Zählt die Anzahl der Vorkommen der */
2: /* einzelnen Zeichen in einer Datei. */
3: #include <stdio.h>
4: #include <stdlib.h>
5:
6: int datei_existiert(char *dateiname);
7:
8: int main(void)
9: {
10: char quelle[80];
11: int ch, index;
12: int count[127];
13: FILE *fp;
14:
15: /* Liest die Namen der Quell- und Zieldatei ein. */
16: fprintf(stderr, "\nGeben Sie den Namen der Quelldatei ein: ");
17: fscanf(stdin, "%80s", quelle);
18:
19: /* Prüft, ob die Quelldatei existiert. */
20: if (!datei_existiert(quelle))
21: {
22: fprintf(stderr, "\n%s existiert nicht.\n", quelle);
23: exit(1);
24: }
25: /* Öffnet die Datei. */
26: if ((fp = fopen(quelle, "rb")) == NULL)
27: {
28: fprintf(stderr, "\nFehler beim Öffnen von %s.\n", quelle);
29: exit(1);
30: }
31: /* Array-Elemente auf Null setzen. */
32: for (index = 31; index < 127 ; index++)
33: count[index] = 0;
34:
35: while ( 1 )
36: {
37: ch = fgetc(fp);
38: /* Bei End-of-File fertig */
39: if (feof(fp))
40: break;
41: /* Nur Zeichen zwischen 32 und 126 zählen. */
42: if (ch > 31 && ch < 127)
43: count[ch]++;
44: }
45:
46: /* Statistik ausgeben. */
47: printf("\nZeichen\tAnzahl\n");
48: for (index = 32; index < 127 ; index++)
49: printf("[%c]\t%d\n", index, count[index]);
50: /* Datei schließen und beenden. */
51: fclose(fp);
52: return(0);
53: }
54:
55: int datei_existiert(char *dateiname)
56: {
57: /* Liefert WAHR zurück, wenn der Dateiname existiert,
58: * und FALSCH, wenn nicht.
59: */
60: FILE *fp;
61: if ((fp = fopen(dateiname, "r")) == NULL)
62: return 0;
63: else
64: {
65: fclose(fp);
66: return 1;
67: }
68: }
Betrachten wir zuerst die Funktion datei_existiert()
in den Zeilen 55 bis 68. Wenn
dieser Funktion ein Dateiname als Argument übergeben wird, liefert sie wahr
zurück,
wenn die Datei existiert, und falsch
, wenn die Datei nicht gefunden wird. Um zu
prüfen, ob die Datei vorhanden ist, versucht die Funktion, die Datei im Lesemodus zu
öffnen (Zeile 61). Die Funktion ist möglichst allgemein gehalten und kann deshalb
auch in anderen Programmen verwendet werden.
Als Nächstes möchte ich Sie darauf aufmerksam machen, dass für die
Bildschirmausgaben, wie zum Beispiel in Zeile 16, die Funktion fprintf()
und nicht
die Funktion printf()
verwendet wird. Da printf()
die Ausgabe immer an stdout
sendet, würde der Anwender keine Nachrichten auf dem Bildschirm erhalten, wenn
die Ausgabe des Programms mit dem Umleitungsoperator in eine Datei umgeleitet
wird. Durch die Verwendung von fprintf()
werden Nachrichten an stderr
gesendet,
ein Stream, der immer mit dem Bildschirm verbunden ist.
Richten Sie zum Schluss Ihr Augenmerk darauf, wie der numerische Wert eines jeden
Zeichens als Index für das Ergebnis-Array (Zeilen 42 und 43) verwendet wird. So stellt
zum Beispiel der numerische Wert 32 ein Leerzeichen dar; deshalb wird das Array-
Element count[32]
verwendet, um alle Leerzeichen aufzunehmen.