Пример 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

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