Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Пример 4

/* Предварительная разметка текста для nroff */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>  /* прототип strchr() */
#include <locale.h>
FILE *fout = stdout; /* канал вывода      */

/* Состояния вывода */
#define SPACE   0       /* пробелы          */
#define TEXT    1       /* текст            */
#define PUNCT   2       /* знаки препинания */

#define UC(c)   ((unsigned char)(c))

/* Вывод строки текста из буфера */
void putstr (FILE *fp, unsigned char *s) {
/* Punct -  знаки препинания, требующие приклеивания к
 *          концу предыдущего слова.
 * PunctS - знаки, всегда требующие после себя пробела.
 * PunctN - знаки, которые могут следовать за знаком
 *          препинания без пробела.
 */
    static char Punct [] = ",:;!?.)"      ;
    static char PunctS[] = ",:;"          ;
    static char PunctN[] = " \t\"'"       ;
#define is(c, set) (strchr(set, UC(c)) != NULL)
    int c, state = TEXT, cprev = 'X';

    while ((c = *s) != '\0') {
    /*  Пробелы */
	if(isspace(c)) state = SPACE;

    /*  Знаки препинания. Пробелы перед ними игнорируются.
     */ else if(is(c, Punct)){
	  switch(state){
	  case SPACE: if(is(cprev, Punct ) && cprev==c && c != ')')
			 putc(' ', fp);
	  /* а просто пробелы - игнорировать */            break;
	  case PUNCT: if(is(cprev, PunctS)) putc(' ', fp); break;
	  }
	  putc(cprev = c, fp); /* выводим сам знак */
	  state = PUNCT;
	} else {
    /*  Несколько пробелов сворачиваем в один */
	  switch(state){
	  case SPACE: putc(' ', fp); break;
	  case PUNCT: if(!is(c, PunctN)) putc(' ', fp); break;
	  }
	  putc(cprev = c, fp); /* сама буква */
	  state = TEXT;
	  if(c == '\\') putc('e', fp);
	}
	s++;
    } /* пробелы в конце строки просто игнорируются */
    putc ('\n', fp);
}
/* Обработать файл с именем name */
void proceed (char *name) {
    FILE *fp;
    static unsigned char inp[2048];
    /* достаточно большой буфер ввода */

    if      (strcmp(name, "-") == 0 ) fp = stdin;
    else if ((fp = fopen (name, "r")) == NULL) {
	fprintf (stderr, "Cannot read %s\n", name);
	return;
    }
    while (fgets (inp, sizeof inp, fp) != NULL) {
	register unsigned char  *s, *p;
	int len = strlen (inp);
	if (len && inp[len - 1] == '\n')
		   inp[--len]   =  '\0';
	if (!*inp) {
	/* .sp N  - пропуск N пустых строк */
space:      fprintf (fout, ".sp 1\n");
	    continue;
	}

    /* обрезать концевые пробелы */
	for(p = NULL, s = inp; *s; ++s){
	    if (!isspace (*s)) p = s;
	}
	if(p) p[1] = '\0';
	else goto space;
    /* p указывает на последний непробел */

/* Удалить переносы слов в конце строки: перенос - это
   минус, прижатый к концу слова         */
	if (*p == '-' && p != inp /* не в начале строки */
		      && isalnum(UC(p[-1])) /* после буквы  */
	){  int c;  *p = '\0'; /* затереть перенос */
/* Читаем продолжение слова из начала следующей строки */
	    while (isspace (c = getc (fp)));
	    ungetc (c, fp);
	    while ((c = getc (fp)) != '\n' && !isspace (c))
		*p++ = c;
	    *p = '\0';
	    if (c != '\n' ){ /* прочли пробел */
	    /* вычитываем ВСЕ пробелы */
	       while (isspace(c = getc (fp)));
	       if(c != '\n') ungetc (c, fp);
	    }
	}
	/* .pp - директива начала абзаца. */
	if (isspace (*inp)) {
	    fprintf (fout, ".pp\n");
	    for (s = inp; isspace (*s); s++);
	    putstr (fout, s);
	}
	else {
	    if (*inp == '.' || *inp == '\'')
		fprintf (fout, "\\&");
	    putstr (fout, inp);
	}
    }
    if( fp != stdin ) fclose (fp);
}

int main (int argc, char *argv[]) {
    int  i;
    setlocale(LC_ALL, "");
    for (i = 1; i < argc; i++)
	proceed (argv[i]);
    return 0; /* exit code */
}

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

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

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...