c++ dirent.h и синтаксис для получения абсолютного пути

Я учусь использовать dirent.h. Хотя процесс увлекательный и интересный, я столкнулся с проблемой использования d_name.

Я хочу сделать две вещи, используя d_name.

  1. рекурсивный поиск по подкаталогам. К этому, когда я столкнусь с файлами типа DT_DIR, я сделаю рекурсивный вызов функции

    void iterateDirectory(char* filePath){
    DIR* dirPtr;
    dirent* entry;
    entry = readdir(dirPtr);
    ...
    }
    

    внутри себя, используя d_name каталога в качестве нового параметра char* filePath. Так,

    if(dirEntry->d_type == DT_DIR){
    entry->d_name;
    iterateDirectory(entry->d_name);
    ...
    }  
    
  2. Открыть все файлы в каталоге. Для этого, когда я сталкиваюсь с файлами DT_REG, я создаю объект ifstream и открываю файл, используя d_name. Так,

    if(dirEntry->d_type == DT_REG){
    entry->d_name;
    ifstream fin(entry->d_name);
    if(fin.is_open)
        cout<<"Opened"<<endl;
    else
        cout<<"Not Opened"<<endl;
    ...
    }  
    

Проблема, с которой я сталкиваюсь, заключается в том, что ни функция void iterateDirectory(), ни функция ifstream fin() не распознают запись->d_name как допустимый ввод. Когда я вызываю функцию итерации, используя d_name, или использую ifstream с entry->d_name, мои проверки, чтобы увидеть, открыт ли каталог или файл, терпят неудачу. Сама функция работает, так как я проверял точно такую ​​же функцию с разными входными данными char*. Единственная проблема, о которой я могу думать, заключается в том, что моя функция не принимает абсолютный путь в качестве параметра.

Мои вопросы заключаются в том, как я могу найти абсолютный путь к данному файлу или подкаталогу в точке итерации. Моим первоначальным решением было использовать "." так как это текущий каталог. Сохраните адрес "." в строку и добавьте "\"+entry->d_name. Но я думаю, что синтаксис неправильный.

Я прав насчет проблемы с абсолютным путем? или есть другая проблема, которую я упускаю? Если это проблема с абсолютным путем, каков синтаксис для получения абсолютного пути к файлу?

P.S.

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

https://github.com/ForeverABoy/dirent.h_practice/blob/master/directoryIterator.cpp

Любая помощь приветствуется. Спасибо!


person Ishiro Kusabi    schedule 26.11.2016    source источник
comment
d_name — это имя файла в каталоге. Если вы opendir()ed filePath для foo/bar, а d_name — это baz, чтобы открыть этот файл, вам, очевидно, нужно открыть foo/bar/baz, а не только то, что вы видите в d_name.   -  person Sam Varshavchik    schedule 26.11.2016
comment
Сэм, спасибо за помощь. Я понимаю, что проблема связана с абсолютным путем, и я пытаюсь найти способ получить абсолютный путь к каталогу из заданного ввода. Использование realpath(entry-›d_name, buffer) не сильно помогло, потому что 1. realpath дает мне каталог сборки моего кода вместо входного каталога. 2. даже с каталогом сборки файлов не обновляет адрес для подкаталогов. после перехода от foo к foo/bar, когда он ищет baz, realpath() дает мне foo/baz вместо foo/bar/baz.   -  person Ishiro Kusabi    schedule 26.11.2016
comment
Используйте realpath() в имени каталога, чтобы получить абсолютный путь к каталогу. Затем добавьте d_name.   -  person Sam Varshavchik    schedule 26.11.2016
comment
Единственный способ, который я могу придумать, - это иметь вектор, содержащий строку или char * версию исходного ввода для каталога. поэтому папки std::vector‹std::string› изначально будут иметь foo в качестве элемента. Затем, как только я прочитаю из foo, если файл является каталогом (bar), я добавлю запись->d_name в вектор. Затем я сделаю folders[0].append(/); папки[0].append(папки[1]); тогда я бы вызвал рекурсивную функцию в folders[0].c_str();   -  person Ishiro Kusabi    schedule 26.11.2016
comment
Возможно, это глупый вопрос, но отличается ли он от выполнения realpath(entry->d_name, buffer)? Какой будет синтаксис для использования realpath в имени каталога? Из вашего примера foo это будет realpath(foo,buffer)?   -  person Ishiro Kusabi    schedule 26.11.2016
comment
Перечитайте страницу руководства для realpath(). Не просто читайте слова. Поймите, что это значит, и все должно быть кристально ясно.   -  person Sam Varshavchik    schedule 26.11.2016
comment
Спасибо, Сэм! Ты прав. Понимание руководства сделало вещи намного яснее! У меня все работает.   -  person Ishiro Kusabi    schedule 26.11.2016


Ответы (1)


Благодаря Сэму Варшавчику я разобрался с проблемой.

Проблема действительно заключалась в том, что функции не вызывались с использованием полных имен путей. Я знал это и немедленно попытался исправить это с помощью realpath(). Проблема заключалась в том, что я использовал реальный путь для записи-> d_name вместо имени каталога.

realpath(entry->d_name, buffer);

Это вернуло каталог сборки вместо входного каталога. Я предполагаю, что это потому, что при запуске кода путь от переменной d_name действительно будет в каталоге сборки.

char* fullPath = realpath(inputPath, buffer);

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

Еще раз спасибо, Сэм. Ты прав. Когда я прочитал и полностью понял, о чем говорится в руководстве по realpath(), все это обрело смысл.

person Ishiro Kusabi    schedule 26.11.2016