C :: Aufgabe #139 :: Lösung #1

1 Lösung Lösung öffentlich
#139

Wörterzählen in Textdateien

Anfänger - C von hollst - 23.12.2016 um 09:50 Uhr
Man schreibe ein Programm, das bei einer beliebigen Textdatei (ASCII)

a) alle Wörter und
b) alle unterschiedlichen Wörter der Längen 1, 2, 3 ... zählt, wobei zwischen Groß- und Kleinbuchstaben nicht zu unterscheiden sei.

Als Wörter-Trennzeichen sind zu verwenden:

a) alle Sonderzeichen (' ', '.', ',', tab ...) sowie Zahlen (0, 1 ... 9) und
b) alle Chars, die nicht zum Aphabet (abc...xyzäöü) gehören (damit wäre a) bereits automatisch erfüllt).

Anmerkungen:
a) Es gibt auch im Deutschen Wörter der Länge 1, z. B. in "a tempo" oder " a priori" oder bei Abkürzungen ("z. B.").
b) Als Beispieltext kann von hier die komplette Bibelausgabe nach Martin Luther 1912 als ASCII-Datei heruntergeladen und verwendet werden (ist mit 4 MB zu lang als Anhang hier, selbst als *.rar noch ca. 1.2 MB).

Viel Spaß und schöne Weihnachten sowie einen guten Rutsch und Start in 2017.
#1
vote_ok
von devnull (8870 Punkte) - 29.12.2016 um 11:17 Uhr
Die u.a. Lösung zählt die Gesamtzahl der Wörter und alle - auch gleiche - Wörter mit 1..10 Zeichen, d.h. Aufgabenteil b) ist noch nicht vollständig umgesetzt.
Die Bibel-Textdatei (keine reine ASCII-Datei) wurde nach UTF-8 konvertiert.

Konsolenausgabe:

Datei <Martin_Luther_Uebersetzung_1912_UTF-8.txt>:
Wortlänge Anzahl
1 1817
2 62246
3 245840
4 122670
5 102349
6 86348
7 41900
8 27035
9 17046
10 10296
Der Text enthält insgesamt 731285 Wörter.

Quellcode ausblenden C-Code
/********************************************
 * wtc.c     count words in text files
 ********************************************/
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
#include <wctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#define LOCALE    "de_DE.utf8"
#define WRDLEN    10

/* search for next word and get its length */
int get_wordlen(FILE *fin)
{
    static bool inwrd = false;
    register wint_t wch;
    register int wdl;

	while ((wch = fgetwc(fin)) != WEOF) {
		if (iswalpha(wch)) {
			if (!inwrd) {
				wdl = 0;
				inwrd = true;
			}
			++wdl;
		}
		else {
			if (inwrd) {
				inwrd = false;
				break;
			}
		}
    }
    /* show illegal wide character error */
    if (ferror(fin))
		if (errno == EILSEQ)
			fprintf(stderr, "illegal character at file position %ld - stopping here\n",
							ftell(fin));
	return (wch==WEOF)?EOF:wdl;
}

/* show counting results */
void show_counts(int wclist[], int wclen, const char *fname)
{
	int n;

	printf("Datei <%s>:\n", fname);
	printf("Wortlänge  Anzahl\n");
	for (n=1; n<=wclen; n++)
		printf("  %3d      %6d\n", n, wclist[n]);
	printf("Der Text enthält insgesamt %d Wörter.\n\n", wclist[0]);
}

/* main: count words for each text file specified as argument */
int main(int argc, char **argv)
{
    int word_count[WRDLEN+1];	/* index 0   : total words counter   */
                                /* index n>0 : word length n counter */
    FILE *fp;
    char *prog = argv[0];
    int gwlen;

	/* set locale */
    if (setlocale(LC_ALL, LOCALE) == NULL) {
        fprintf(stderr, "can't set locale to %s\n", LOCALE);
        exit(EXIT_FAILURE);
	}

	/* loop: read args list */
    if (argc > 1) {
        while (--argc > 0) {
			memset(word_count, 0, sizeof(word_count));
            if ((fp = fopen(*++argv, "r")) == NULL) {
                fprintf(stderr, "%s: can't open %s\n", prog, *argv);
                exit(EXIT_FAILURE);
            } else {
				while ((gwlen = get_wordlen(fp)) != EOF) {
					if (gwlen <= WRDLEN)
						++word_count[gwlen];
					++word_count[0];
				}
                fclose(fp);
				show_counts(word_count, WRDLEN, *argv);
            }
		}
    } else
        fprintf(stderr, "usage: %s file1 file2 ...\n", prog);

    return 0;
}

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben