Хрестоматия по программированию на Си в Unix



Системные вызовы и взаимодействие с UNIX. Хрестоматия по программированию на Си в Unix - стр. 4


/* ОТСЕЧЬ ПОСЛЕДНЮЮ КОМПОНЕНТУ ПУТИ */ struct savech parentdir(char *path){ char *last = strrchr( path, SLASH ); char *first = strchr ( path, SLASH ); struct savech sp; sp.s = NULL; sp.c = '\0';

if( last == NULL ) return sp; /* не полное имя */ if( last[1] == '\0' ) return sp; /* корневой каталог */ if( last == first ) /* единственный слэш: /DIR */ last++; sp.s = last; sp.c = *last; *last = '\0'; return sp; } #define isfullpath(s) (*s == SLASH) /* КАНОНИЗИРОВАТЬ ИМЯ ФАЙЛА */ void canon( char *where, /* куда поместить ответ */ char *cwd, /* полное имя текущего каталога */ char *path /* исходное имя для канонизации */ ){ char *s, *slash; /* Сформировать имя каталога - точки отсчета */ if( isfullpath(path)){ s = strchr(path, SLASH); /* @ */ strncpy(where, path, s - path + 1); where[s - path + 1] = '\0'; /* или даже просто strcpy(where, "/"); */ path = s+1; /* остаток пути без '/' в начале */ } else strcpy(where, cwd);

/* Покомпонентный просмотр пути */ do{ if(slash = strchr(path, SLASH)) *slash = '\0'; /* теперь path содержит очередную компоненту пути */ if(*path == '\0' !strcmp(path, ".")) ; /* то просто проигнорировать "." и лишние "///" */ else if( !strcmp(path, "..")) (void) parentdir(where); else{ int len = strlen(where); /* добавить в конец разделяющий слэш */ if( where[len-1] != SLASH ){ where[len] = SLASH; where[len+1] = '\0'; } strcat( where+len, path ); /* +len чисто для ускорения поиска * конца строки внутри strcat(); */ } if(slash){ *slash = SLASH; /* восстановить */ path = slash + 1; } } while (slash != NULL); } char cwd[256], input[256], output[256]; void main(){ /* Узнать полное имя текущего каталога. * getcwd() - стандартная функция, вызывающая * через popen() команду pwd (и потому медленная). */ getcwd(cwd, sizeof cwd); while( gets(input)){ canon(output, cwd, input); printf("%-20s -> %s\n", input, output); } }

В этом примере (изначально писавшемся для MS DOS) есть "странное" место, помеченное /*@*/. Дело в том, что в DOS функция isfullpath была способна распознавать имена файлов вроде C:\aaa\bbb, которые не обязательно начинаются со слэша.

Мультиплексирование ввода-вывода.




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