Пример 5

/* Программа, распечатывающая слова в строках файла в обратном порядке */ #include <stdio.h> #include <ctype.h> #include <string.h> #include <locale.h> #define MAXL 255 /* макс. длина строки */ /* Если бы мы не включили ctype.h, то мы должны были бы определить * #define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\f') */ main ( argc, argv ) char **argv;{ setlocale(LC_ALL, ""); if( argc == 1 ){ /* программа вызвана без аргументов */ munch( "" ); }else{ /* аргументы программы - имена файлов */ while( argv[ 1 ] ){ munch( argv[1] ); argv++; argc--; } } total(); exit(0); } /* обработать файл с именем name */ munch( name ) char *name; { char l[MAXL]; /* буфер для очередной строки */ int len; /* длина этой строки */ char *words[50]; /* таблица полей строки */ char **s; /* служебная */ int nwords; /* число слов в строке */ FILE *fp; if( name == NULL || !*name ) fp = stdin; /* стандартный ввод */ else if( (fp = fopen( name, "r" )) == NULL ){ fprintf( stderr, "Не могу открыть файл %s\n", name ); return; } printf( "----------------------------%s----\n", name ); while( fgets( l, MAXL, fp ) != NULL ){ len = strlen( l ); if( len && l[len-1] == '\n' ) l[--len] = '\0' ; if( nwords = parse( l, words)){ /* распечатка слов в обратном порядке */ for( --nwords; nwords >= 0; nwords-- ){ printf( "%s ", words[ nwords] ); add( words[ nwords ] ); } } putchar ('\n'); } if( fp != stdin ) fclose( fp ); } /* разобрать строку на слова */ parse( s, tabl ) register unsigned char *s; unsigned char *tabl[]; { char eol = 0; int nwords = 0; while ( !eol ){ /* пропустить пробелы и табуляции */ while(isspace(*s)) s++; if( !*s ) /* строка кончилась */ break; *tabl++ = s; nwords++; /* начало очередного слова */ /* пока не пробел и не конец строки */ while( *s && !isspace(*s))s++; /* указатель стоит на символе, следующем за словом */ if( ! *s ) eol ++; *s = '\0'; /* закрыли Слово, начинаем Дело */ s++; } *tabl = NULL; return nwords; } /* построение таблицы слов, встречающихся в файле */ #define MAXWORDS 1024 struct W{ int ctr; /* число вхождений слова */ char *wrd; /* слово */ }w [MAXWORDS]; /* таблица */ int busy = 0 ; /* занято в таблице */ extern char *malloc(); /* Добавить слово в таблицу */ add( word ) char *word; { register i; static alert = 1; /* нет ли уже слова в таблице ? */ /* если есть - просто увеличить счетчик */ for( i = 0; i < busy ; i++ ){ if( !strcmp( word, w[i].wrd )){ w[i].ctr++; return; } } if( busy >= MAXWORDS ){ if( alert ){ fprintf( stderr, "Переполнение таблицы слов\7\n"); alert = 0; } return; } /* нет, слова нет. Заносим: */ w[busy].wrd = malloc( strlen( word ) + 1 ); /* 1 байт под символ \0 */ if( w[busy].wrd == NULL ){ fprintf( stderr, "Мало памяти\n"); busy = MAXWORDS+1; /* якобы переполнение */ return; } w[busy].ctr = 1; strcpy( w[busy].wrd, word ); busy++; } compare( a, b ) struct W *a, *b; { return strcoll( a-> wrd, b-> wrd ); /* strcoll сравнивает слова в алфавитном порядке */ } /* выдача всех слов, встреченных в тексте, и числа их вхождений */ total(){ register i; /* сортируем слова по алфавиту */ qsort( w, busy, sizeof(struct W), compare ); printf( "-----|-----------ИТОГ---------------\n"); for( i=0; i < busy; i++ ) printf( "%4d | %s\n", w[i].ctr, w[i].wrd ); }

© Copyright А. Богатырев, 1992-95
Си в UNIX

Назад | Содержание | Вперед