Чтение онлайн

ЖАНРЫ

UNIX — универсальная среда программирования
Шрифт:

buf[strlen(buf)-1] = '\0'; /* suppress \n */

fprintf(stderr, "%s? ", buf);

if (ttyin == 'y') {

sscanf(buf, "%d", &pid);

kill(pid, SIGKILL);

}

}

 exit(0);

}

Мы писали программу, чтобы использовать

ps -ag
(этот флаг системно зависим), но если вы не являетесь привилегированным пользователем, то можете уничтожать лишь свои собственные процессы.

Первый вызов

fgets
выбирает заголовок из
ps
; интересно выяснить, что случится, если попытаться уничтожить "процесс", соответствующий данному заголовку.

Функция

sscanf
представляет
собой член семейства
scanf(3)
для форматного преобразования входной строки. Она преобразует строку, а не файл. Вызов
kill
из системы посылает специальный сигнал процессу; сигнал
SIGKILL
, определенный в
<signal.h>
, не может быть перехвачен или проигнорирован. Вы можете вспомнить пятую главу, где его численное значение равно девяти, но лучше использовать символические константы из файлов макроопределений, чем включать в свои программы загадочные числа.

Если аргументы отсутствуют,

zap
предоставляет каждую строку выходного потока
ps
как возможность для выбора. При наличии аргумента
zap
предлагает только те выходные строки
ps
, которые ему соответствуют. Функция
strindex(s1, s2)
проверяет, соответствует ли аргумент какой-либо части строки выходного потока
ps
, используя
strncmp
(см. табл. 6.2). Функция
strindex
возвращает позицию
s2
в
s1
или -1, если ее там нет.

strindex(s, t) /* return index of t in s, -1 if none */

 char *s, *t;

{

 int i, n;

 n = strlen(t);

 for (i = 0; s[i] != '\0'; i++)

if (strncmp(s+i, t, n) == 0)

return i;

 return -1;

}

В табл. 6.4 представлены широко используемые функции из стандартной библиотеки ввода вывода.

fp=fopen(s, mode)
Открыть файл
s
; значения
mode "r"
,
"w"
,
"a"
соответствуют чтению, записи и добавлению (при ошибке возвращается NULL)
c=gets(fp)
Читать символ:
getchar
это
getc(stdin)
putc(c, fp)
Записать символ:
putchar(c)
это
putc(c, stdout)
ungetc(c, fp)
Вернуть символ во входной файл
fp
; можно вернуть не более одного символа за раз
scanf(fmt, a1, ...)
Читать символы из
stdin
в
a1
,
...
в соответствии с
fmt
. Каждый
ai
должен быть указателем
fscanf(fp,...)
Читать из файла
fp
sscanf(s,...)
Читать из строки
s
printf(fmt, a1, ...)
Форматировать
a1
, ... в соответствии с
fmt
; печатать в
stdout
fprintf(fp, ...)
Печатать
...
в файл
fp
sprintf(s, ...)
Печатать
...
в строку s
fqets(s, n, fp)
Читать не более
n
символов в
s
из
fp
(возвращается
NULL
по концу файла)
fputs(s, fp)
Печатать
строку
s
в файл
fp
fflush(fp)
Занести буферизованные данные выходного потока в файл
fp
fclose(fp)
Закрыть файл
fp
fp=popen(s, mode)
Открыть программный канал для команды
s
(см.
fopen
)
pclose(fp)
Закрыть программный канал
fp
system(s)
Запустить команду
s
и ждать ее окончания

Таблица 6.4: Полезные стандартные функции ввода-вывода

Упражнение 6.11

Модифицируйте

zap
так, чтобы можно было применять любое число аргументов. В настоящем виде
zap
высвечивает на экране строку, соответствующую выбранному варианту. Будет она делать это? Если нет, модифицируйте программу соответствующим образом. Подсказка:
getpid(2)
.

Упражнение 6.12

Постройте

fgrep(1)
на основе
strindex
. Сравните время работы при сложных поисках, например 10 слов на документ. Почему
fgrep
выполняется быстрее?

6.8 Диалоговая программа сравнения файлов:

idiff

Поддерживать две чем-то отличающиеся версии файла, каждая из которых содержит часть нужного вам файла, довольно распространенная проблема. Зачастую она возникает в тех случаях, когда изменения вносятся независимо двумя разными людьми. Программа

diff
подскажет вам, чем различаются файлы, но вы не получите никакой помощи, если захотите выбрать какую-то информацию из одного файла, а какую-то из другого.

В этом разделе мы напишем программу

idiff
(диалоговая
diff
), которая предоставляет пользователю каждую порцию выходного потока
diff
и предлагает ему возможность выбора фрагментов "от и до" или их редактирования. Программа
idiff
помещает выбранные фрагменты в соответствующем порядке в файл
idiff.out
. Допустим, даны такие два файла:

file1: file2:

This is This is

a test not a test

of of

your our

skill ability.

and comprehension.

diff
вырабатывает следующее:

$ diff file1 file2

2c2

< a test

– --

> not a test

4,6c4,5

< your

< skill

< and comprehension.

– --

> our

> ability.

$

Диалог с

idiff
может выглядеть так:

$ idiff file1 file2

2c2
Первое различие

< a test

– --

> not a test

? >
Пользователь выбрал вторую версию

4,6с4,5
Второе различие

< your

< skill

< and comprehension.

– --

> our

> ability.

? <
Пользователь выбрал первую (<) версию

idiff output in file idiff.out

$ cat idiff.out
Выходной поток направляется в этот файл

This is

not a test of

Поделиться с друзьями: