Пример 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 www.abyss-group.narod.ru
Си в UNIX

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

Hosted by uCoz