p = guess; /* copy next component into guess */ for (; *old != '/' && *old != '\0'; old++) if (p < guess+DIRSIZ) *p++ = *old; *p = '\0'; if (mindist(newname, guess, best) >= 3) return -1; /* hopeless */ for (p = best; *new = *p++; ) /* add to end */ new++; /* of newname */ }}mindist(dir, guess, best) /* search dir for guess */ char *dir, *guess, *best;{ /* set best, return distance 0..3 */ int d, nd, fd; struct { ino_t ino; char name[DIRSIZ+1]; /* 1 more than in dir.h */ } nbuf; nbuf.name[DIRSIZ] = '\0'; /* +1 for terminal '\0' */ if (dir[0] == '\0') /* current directory */ dir = "."; d = 3; /* minimum distance */ if ((fd = open(dir, 0)) == -1) return d; while (read(fd,(char *)&nbuf, sizeof(struct direct)) > 0) if (nbuf.ino) { nd = spdist(nbuf.name, guess); if (nd <= d && nd != 3) { strcpy(best, nbuf.name); d = nd; if (d == 0) /* exact match */ break; } } close(fd); return d;Если имя каталога, данное
mindist'.'mindistreadsizeofЕсли строка каталога в данный момент не используется (поскольку файл удален), то поле индекса в ней равно нулю и она пропускается. Проверка расстояния осуществляется как
if (nd <= d...)а не как
if (nd < d...)поэтому любой одиночный символ дает лучшее совпадение, чем имя
'.'/* spdist: return distance between two names */ /* * very rough spelling metric: * 0 if the strings are identical * 1 if two chars are transposed * 2 if one char wrong, added or deleted * 3 otherwise */#define EQ(s,t) (strcmp(s,t) == 0)spdist(s, t) char *s, *t;{ while (*s++ == *t) if (*t++ == '\0') return 0; /* exact match */ 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;}Поскольку у нас есть
spnamep/* p: print input in chunks (version 4) */#include <stdio.h>#define PAGESIZE 22char *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++)