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

ЖАНРЫ

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

 if (*--s) {

if (*t) {

if (s[1] && t[1] && *s == t[1] && *t == s[1] && EQ(s+2, t+2))

return 1; /* transposition */

if (EQ(s+1, t+1))

return 2; /* 1 char mismatch */

}

if (EQ(s+1, t))

return 2; /* extra character */

 }

 if (*t && EQ(s, t+1))

return 2; /* missing character */

 return 3;

}

Поскольку

у нас есть
spname
, несложно вставить функции по коррекции написания в
p
:

/* p: print input in chunks (version 4) */

#include <stdio.h>

#define PAGESIZE 22

char *progname; /* program name for error message */

main(argc, argv)

 int argc;

 char *argv[];

{

 FILE *fp, *efopen;

 int i, pagesize = PAGESIZE;

 char *p, *getenv, buf[BUFSIZ];

 progname = argv[0];

 if ((p=getenv("PAGESIZE")) != NULL)

pagesize = atoi(p);

 if (argc > 1 && argv[1][0] == '-') {

pagesize = atoi(&argv[1][1]);

argc--;

argv++;

 }

 if (argc == 1)

print(stdin, pagesize);

 else

for (i = 1; i < argc; i++)

switch (spname(argv[i], buf)) {

case -1: /* no match possible */

fp = efopen(argv[i], "r");

break;

case 1: /* corrected */

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

if (ttyin == 'n')

break;

argv[i] = buf; /* fall through... */

case 0: /* exact match */

fp = efopen(argv[i], "r");

print(fp, pagesize);

fclose(fp);

}

 exit(0);

}

Функции по коррекции написания не следует слепо применять к каждой программе, которая использует имена файлов. Они хорошо сочетаются с

p
, так как
p
— диалоговая программа, но подходят и для недиалоговых программ.

Упражнение 7.5

Насколько вы можете улучшить эвристику для выявления наилучшего совпадения в

spname
? Например, неразумно рассматривать регулярный файл так, как если бы он был каталогом; текущая версия это допускает.

Упражнение: 7.6

Имя

tx
совпадает с каким-либо именем
tc
, которое оказывается последним в каталоге для любого одиночного символа
с
. Можете ли вы придумать лучшую меру расстояния? Реализуйте ее и посмотрите, насколько хорошо эта конструкция работает с реальными пользователями.

Упражнение 7.7

Работает ли

p
ощутимо быстрее, если чтение каталога выполняется большими порциями?

Упражнение 7.8

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

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

Упражнение 7.9

Какую пользу могли бы извлечь другие программы из

spname
? Сконструируйте отдельную программу, которая корректировала бы другие аргументы прежде, чем передать их другой программе, как в

$ fix prog filenames...

Можете написать версию

cd
, которая использует
spname
? Как бы вы ее встроили?

7.3 Файловая система: индексные дескрипторы

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

Для начала разберемся в самом индексном дескрипторе. Часть индексного дескриптора описывается структурой stat, определенной в

<sys/stat.h>
:

struct stat /* структура, возвращаемая stat */

{

 dev_t st_dev; /* устройство, содержащее файл */

 ino_t st_ino; /* индекс */

 short st_mod; /* биты режима */

 short st_nlink; /* число связей файла */

 short st_uid; /* пользовательский идентификатор

владельца */

 short st_gid; /* идентификатор группы владельцев */

 dev_t st_rdev; /* для специальных файлов */

 off_t st_size; /* размер файла в символах */

 time_t st_atime; /* время последнего чтения файла */

 time_t st_mtime; /* время последней записи

или создания файла */

 time_t st_ctime; /* время последнего изменения

индексного дескриптора или файла */

}

Большинство полей поясняются примечаниями. Типы вроде

dev_t
и
ino_t
определены в
<sys/types.h>
, как отмечено выше. Поле
st_mode
содержит множество флагов, описывающих файл; для удобства определения флагов также являются частью файла
<sys/stat.h>
:

#define S_IFMT 0170000 /* тип файла */

#define S_IFDIR 0040000 /* каталог */

#define S_IFCHR 0020000 /* байт-ориентированный */

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