Получение имени каталога из имени файла - PullRequest
74 голосов
/ 18 июня 2010

У меня есть имя файла (C: \ folder \ foo.txt), и мне нужно получить имя папки (C: \ folder) в неуправляемом C ++. В C # я бы сделал что-то вроде этого:

string folder = new FileInfo("C:\folder\foo.txt").DirectoryName;

Есть ли функция, которая может использоваться в неуправляемом C ++ для извлечения пути из имени файла?

Ответы [ 11 ]

142 голосов
/ 18 июня 2010

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

boost::filesystem::path p("C:\\folder\\foo.txt");
boost::filesystem::path dir = p.parent_path();
62 голосов
/ 18 июня 2010

Пример из http://www.cplusplus.com/reference/string/string/find_last_of/

// string::find_last_of
#include <iostream>
#include <string>
using namespace std;

void SplitFilename (const string& str)
{
  size_t found;
  cout << "Splitting: " << str << endl;
  found=str.find_last_of("/\\");
  cout << " folder: " << str.substr(0,found) << endl;
  cout << " file: " << str.substr(found+1) << endl;
}

int main ()
{
  string str1 ("/usr/bin/man");
  string str2 ("c:\\windows\\winhelp.exe");

  SplitFilename (str1);
  SplitFilename (str2);

  return 0;
}
23 голосов
/ 18 июня 2010

Для этого есть стандартная функция Windows, PathRemoveFileSpec .Если вы поддерживаете только Windows 8 и более поздние версии, настоятельно рекомендуется использовать PathCchRemoveFileSpec .Среди других улучшений, оно больше не ограничено MAX_PATH (260) символами.

21 голосов
/ 10 мая 2017

В C ++ 17 существует класс std::filesystem::path, использующий метод parent_path.

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
    for(fs::path p : {"/var/tmp/example.txt", "/", "/var/tmp/."})
        std::cout << "The parent path of " << p
                  << " is " << p.parent_path() << '\n';
}

Возможный вывод:

The parent path of "/var/tmp/example.txt" is "/var/tmp"
The parent path of "/" is ""
The parent path of "/var/tmp/." is "/var/tmp"
10 голосов
/ 08 января 2016

Почему это должно быть так сложно?

#include <windows.h>

int main(int argc, char** argv)         // argv[0] = C:\dev\test.exe
{
    char *p = strrchr(argv[0], '\\');
    if(p) p[0] = 0;

    printf(argv[0]);                    // argv[0] = C:\dev
}
5 голосов
/ 18 июня 2010

Используйте boost :: filesystem. В любом случае он будет включен в следующий стандарт, так что вы также можете к нему привыкнуть.

2 голосов
/ 27 июля 2018
 auto p = boost::filesystem::path("test/folder/file.txt");
 std::cout << p.parent_path() << '\n';             // test/folder
 std::cout << p.parent_path().filename() << '\n';  // folder
 std::cout << p.filename() << '\n';                // file.txt

Вам может потребоваться p.parent_path().filename(), чтобы получить имя родительской папки.

2 голосов
/ 18 июня 2010

_splitpath - хорошее CRT-решение.

1 голос
/ 22 июля 2017

Я так удивлен, что никто не упомянул стандартный способ в Posix

Пожалуйста, используйте basename / dirname конструкции.

человек с базовым именем

0 голосов
/ 10 марта 2015

Просто используйте это: ExtractFilePath (your_path_file_name)

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