Пример 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
Назад | Содержание | Вперед