Подтвердить что ты не робот

Получить каталог из пути к файлу С++

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

string filename = "C:\MyDirectory\MyFile.bat" 

В этом примере я должен получить "C:\MyDirectory".

4b9b3361

Ответ 1

Инициализация неверна, поскольку вам нужно избежать обратных косых черт:

string filename = "C:\\MyDirectory\\MyFile.bat";

Чтобы извлечь каталог, если он есть:

string directory;
const size_t last_slash_idx = filename.rfind('\\');
if (std::string::npos != last_slash_idx)
{
    directory = filename.substr(0, last_slash_idx);
}

Ответ 3

Быстрое и грязное:

Обратите внимание, что вы должны также искать /, потому что разрешен альтернативный разделитель путей в Windows

#include <string>
#include <iostream>

std::string dirnameOf(const std::string& fname)
{
     size_t pos = fname.find_last_of("\\/");
     return (std::string::npos == pos)
         ? ""
         : fname.substr(0, pos);
}

int main(int argc, const char *argv[])
{
     const std::string fname = "C:\\MyDirectory\\MyFile.bat";

     std::cout << dirnameOf(fname) << std::endl;
}

Ответ 4

Способ MFC;

#include <afx.h>

CString GetContainingFolder(CString &file)
{
    CFileFind fileFind;
    fileFind.FindFile(file);
    fileFind.FindNextFile();
    return fileFind.GetRoot();
}

или даже проще

CString path(L"C:\\my\\path\\document.txt");
path.Truncate(path.ReverseFind('\\'));

Ответ 6

Очень простое кросс-платформенное решение (в соответствии с этот пример для string::find_last_of):

std::string GetDirectory (const std::string& path)
{
    size_t found = path.find_last_of("/\\");
    return(path.substr(0, found));
}

Это работает для обоих случаев, когда косые черты могут быть либо обратными, либо направленными вперед (или смешанными), поскольку он просто ищет последнее вхождение либо в строке path.

Однако мои личные предпочтения - использование библиотек Boost:: Filesystem для обработки таких операций. Пример:

std::string GetDirectory (const std::string& path)
{
    boost::filesystem::path p(path);
    return(p.parent_path().string());
}

Хотя, если получение пути к каталогу из строки является единственной необходимой функциональностью, то Boost может быть немного избыточным (особенно, поскольку Boost:: Filesystem является одной из немногих библиотек Boost, которые не являются только заголовками). Тем не менее, AFIK, Boost:: Filesystem были одобрены для включения в стандарт TR2, но могут быть недоступны до появления стандарта С++ 14 или С++ 17 (вероятно, последний, основанный на этот ответ), поэтому в зависимости от вашего компилятора (и когда вы это читаете) вам может даже не понадобиться компилировать их отдельно, так как они могут быть включены в вашу систему уже. Например, Visual Studio 2012 уже может использовать некоторые компоненты файловой системы TR2 (согласно этот пост), хотя я не пробовал это с тех пор Я все еще использую Visual Studio 2010...

Ответ 7

Как вопрос старый, но я хотел бы добавить ответ, чтобы он помог другим.
в Visual С++ вы можете использовать массив CString или char также

CString filename = _T("C:\\MyDirectory\\MyFile.bat");  
PathRemoveFileSpec(filename); 

ВЫВОД:

C:\MyDirectory

Включить Shlwapi.h в ваши файлы заголовков.

MSDN LINK здесь вы можете проверить пример.

Ответ 8

Это правильное решение winapi:

CString csFolder = _T("c:\temp\file.ext");
PathRemoveFileSpec(csFolder.GetBuffer(0));
csFolder.ReleaseBuffer(-1);

Ответ 9

С++ 17 предоставляет std :: filesystem :: path. Это может быть доступно в С++ 11 в; ссылка с -lstdС++ фс. Обратите внимание, что функция не проверяет существующий путь; используйте std :: filesystem :: status для определения типа файла (который может быть filetype :: notfound)

Ответ 10

Путь Жук)

#include<tchar.h>

int GetDir(TCHAR *fullPath, TCHAR *dir) {
    const int buffSize = 1024;

    TCHAR buff[buffSize] = {0};
    int buffCounter = 0;
    int dirSymbolCounter = 0;

    for (int i = 0; i < _tcslen(fullPath); i++) {
        if (fullPath[i] != L'\\') {
            if (buffCounter < buffSize) buff[buffCounter++] = fullPath[i];
            else return -1;
        } else {
            for (int i2 = 0; i2 < buffCounter; i2++) {
                dir[dirSymbolCounter++] = buff[i2];
                buff[i2] = 0;
            }

            dir[dirSymbolCounter++] = fullPath[i];
            buffCounter = 0;
        }
    }

    return dirSymbolCounter;
}

Использование:

TCHAR *path = L"C:\\Windows\\System32\\cmd.exe";
TCHAR  dir[1024] = {0};

GetDir(path, dir);
wprintf(L"%s\n%s\n", path, dir);

Ответ 11

Вы можете просто найти последний "\", а затем отрезать строку:

string filePath = "C:\MyDirectory\MyFile.bat" 
size_t slash = filePath.find_last_of("\");
string dirPath = (slash != std::string::npos) ? filePath.substr(0, slash) : filePath;

убедитесь, что в Linux для поиска "/" вместо "\":

size_t slash = filePath.find_last_of("/");