Таблица 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
. Допустим, даны такие два файла:
<b>file1: file2:</b>
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
your skill
and comprehension.
$
Если вместо
<
или
>
выдан ответ
е
,
idiff
вызывает
ed
с двумя группами уже прочитанных строк. Если вторым был ответ
е
, буфер редактора выглядел бы следующим образом:
your
skill
and comprehension.
---
our
ability.
Все, что пишется редактором обратно в файл, идет в окончательный выходной поток.
И, наконец, любая команда может быть выполнена внутри
idiff
с помощью временного выхода посредством
!cmd.
Технически самая трудная часть работы
diff
, и она уже выполнена. Таким образом, в задачи
idiff
входит разбор выходного потока
diff
, открытие, закрытие, чтение и считывание соответствующих файлов в нужное время. Главная функция
idiff
поддерживает файлы и запускает процесс
diff
:
/* idiff: interactive diff */
#include <stdio.h>
#include <ctype.h>
char *progname;
#define HUGE 10000 /* large number of lines */
main(argc, argv)
int argc;
char *argv[];
{
FILE *fin, *fout, *f1, *f2, *efopen();
char buf[BUFSIZ], *mktemp();
char *diffout = "idiff.XXXXXX";
progname = argv[0];
if (argc != 3) {
fprintf(stderr, "Usage: idiff file1 file2\n");
exit(1);
}
f1 = efopen(argv[1], "r");
f2 = efopen(argv[2], "r");