получить каталог из пути к файлу c ++ - PullRequest
18 голосов
/ 15 декабря 2011

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

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

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

Ответы [ 11 ]

17 голосов
/ 15 декабря 2011

Используйте функцию Boost.filesystem parent_path ().

Ex. аргумент c: / foo / bar => c: / foo

Больше примеров здесь: таблица разложения пути и учебник здесь .

16 голосов
/ 15 декабря 2011

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

Обратите внимание, что необходимо также искать /, потому что в 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;
}
15 голосов
/ 15 декабря 2011

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

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);
}
12 голосов
/ 31 января 2013

Способ 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('\\'));
5 голосов
/ 12 января 2016

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

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

ВЫХОД:

C: \ MyDirectory

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

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

5 голосов
/ 15 декабря 2011

Вы можете использовать функцию _spliltpath, доступную в заголовке stdlib.h. Пожалуйста, обратитесь к этой ссылке для того же.

http://msdn.microsoft.com/en-us/library/aa273364%28v=VS.60%29.aspx

3 голосов
/ 13 февраля 2015

Очень простое кроссплатформенное решение (адаптировано из этого примера для 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, но может не быть полностью доступным до стандарта C ++ 14 или C ++ 17 (вероятно, последний, основанный на этот ответ ), поэтому, в зависимости от вашего компилятора (и когда вы читаете это), вам может даже не потребоваться компилировать их отдельно, поскольку они могут уже быть включены в вашу систему.Например, Visual Studio 2012 уже может использовать некоторые компоненты файловой системы TR2 (согласно в этом посте ), хотя я не пробовал, поскольку я все еще использую Visual Studio 2010 ...

2 голосов
/ 10 марта 2016

Это правильное решение для Winapi:

CString csFolder = _T("c:\temp\file.ext");
PathRemoveFileSpec(csFolder.GetBuffer(0));
csFolder.ReleaseBuffer(-1);
1 голос
/ 14 января 2019

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

0 голосов
/ 29 января 2018

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

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("/");

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...