Чтобы получить путь к каталогу в обратном направлении от пути к файлу

#c #linux #recursion

#c #linux #рекурсия

Вопрос:

Предположим, у меня есть имя файла /A/B/C/d.txt,

Я хочу напечатать путь к каталогу в обратном порядке,

 /A/B/C/
/A/B/
/A/
  

Ниже приведена программа, использующая рекурсию для вывода пути к каталогу в обратном порядке.

 #include <stdio.h>
#include <libgen.h>
#include <string.h>
#include <stdlib.h>

void parsepath(const char *dirpath)
{
    char* dirPathTemp;  
    char* dirname;
    char path[255];  

    dirPathTemp = strdup(dirpath);
    dirname = dirname(dirPathTemp);     
    strcpy(path, dirname);

    free(dirPathTemp);  

    printf("path = %sn", path);    

    if (0 != strcmp(path, "/"))
        parsepath(path);
}

int main(int argc, char *argv[])
{
    parsepath("/A/B/C/d.txt");

    return 0;
}
  

Есть ли какой-либо другой способ сделать это без рекурсии? Спасибо.

Комментарии:

1. О, черт возьми. Простой цикл сделает свое дело — просто проверяйте отдельные символы, а не полагайтесь на строковые функции. Просто пройдите в обратном направлении по пути. Кстати, strdup() может подойти для Linux, но не является стандартным C.

2. Спасибо за подсказку.

Ответ №1:

Следующий алгоритм прост: каждый раз, когда он ищет во входной строке последнее вхождение '/' , заменяет его на '' (маркер конца строки) и печатает его, продолжая, пока в path больше не останется косых черт. Необходимо скопировать входную строку, поскольку ее необходимо изменить на месте:

 #include <stdio.h>
#include <string.h>

void parsepath(const char *dirpath)
{
    char *p = strdup(dirpath);
    char *lastslash;
    while(lastslash = strrchr(p, '/')) {
        *lastslash = '';
        printf("%sn", p);
    }
    free(p);
}

int main(void) {
    parsepath("/A/B/C/d.txt");
    return 0;
}
  

Примечание: strrchr() выполняется поиск входной строки с самого начала, что не является оптимальным. Поскольку каждый раз требуется последнее использование косой черты, поиск в обратном направлении был бы предпочтительнее. Вот что делает memrchr() функция. Замена strrchr() на memrchr() оставлена в качестве упражнения для читателя.

Комментарии:

1. Это выглядит просто. Спасибо за примечания к memchr.