Pobieranie nazwy katalogu z nazwy pliku

Mam nazwę pliku (C:\folder\foo.txt) i muszę odzyskać nazwę folderu (C:\folder) w niezarządzanym C++. W C# zrobiłbym coś takiego:

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

Czy istnieje funkcja, która może być używana w niezarządzanym C++ do wyodrębniania ścieżki z nazwy pliku?

Author: Jon Tackabury, 2010-06-18

11 answers

Istnieje standardowa funkcja Windows, PathRemoveFileSpec . Jeśli obsługujesz tylko System Windows 8 i nowszy, zaleca się użycie PathCchRemoveFileSpec. Wśród innych ulepszeń nie jest już ograniczony do MAX_PATH (260) znaków.

 23
Author: Andreas Rejbrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-31 16:53:30

Za Pomocą Boost.System plików:

boost::filesystem::path p("C:\\folder\\foo.txt");
boost::filesystem::path dir = p.parent_path();
 132
Author: AraK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-18 17:11:51

Przykład z 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;
}
 51
Author: corsiKa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-18 17:07:08

Według cppreference.com, experimental header library support for C++17 / 1Z with the class std::experimental::filesystem::path korzystanie z metody parent_path.

#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::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';
}

Możliwe wyjście:

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"
 9
Author: Alessandro Jacopson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-08 17:22:31

Dlaczego to musi być takie skomplikowane?

#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
}
 8
Author: toster-cx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-07 22:58:49

Użyj boost:: filesystem. I tak zostanie on włączony do następnego standardu, więc równie dobrze możesz się do niego przyzwyczaić.

 5
Author: Crazy Eddie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-18 17:11:23

_splitpath to ładne rozwiązanie CRT.

 2
Author: Ofek Shilon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-18 17:39:42

Jestem tak zaskoczony, że nikt nie wspomniał o standardowym sposobie w Posix

Proszę używać basename / dirname konstrukcji.

Man basename

 1
Author: Utkarsh Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-21 22:40:22
 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

Może być konieczne p.parent_path().filename(), Aby uzyskać nazwę folderu nadrzędnego.

 1
Author: srbcheema1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-27 16:41:18

Standardowy C++ nie zrobi dla Ciebie wiele w tym zakresie, ponieważ nazwy ścieżek są specyficzne dla platformy. Można ręcznie parsować łańcuch znaków (jak w odpowiedzi glowcodera), korzystać z udogodnień systemu operacyjnego (np. http://msdn.microsoft.com/en-us/library/aa364232 (V = VS.85).aspx ), lub prawdopodobnie najlepszym podejściem, możesz użyć biblioteki systemu plików innej firmy, takiej jak boost:: filesystem.

 0
Author: Cogwheel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-18 17:09:55

Po prostu użyj tego: ExtractFilePath (your_path_file_name)

 -3
Author: fxPiotr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-10 02:18:27