Mam nazwę pliku (C: \ folder \ foo.txt) i muszę pobrać 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órej można użyć w niezarządzanym C ++ do wyodrębnienia ścieżki z nazwy pliku?
Korzystanie z Boost.Filesystem:
boost::filesystem::path p("C:\\folder\\foo.txt"); boost::filesystem::path dir = p.parent_path();
źródło
p.remove_filename()
zmodyfikujep
na miejscu i może być wdrożony wydajniej niżp = p.parent_path()
parent_path()
from"C:\\folder"
spowoduje rozszerzenie"C:"
.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; }
źródło
W C ++ 17 istnieje klasa
std::filesystem::path
korzystająca z metodyparent_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'; }
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"
źródło
.remove_filename()
metoda.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 }
źródło
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()
uzyskanie nazwy folderu nadrzędnego.źródło
Użyj boost :: filesystem. I tak zostanie włączony do następnego standardu, więc równie dobrze możesz się do niego przyzwyczaić.
źródło
_splitpath to fajne rozwiązanie CRT.
źródło
Jestem tak zaskoczony, że nikt nie wspomniał o standardowym sposobie w Posix
Użyj
basename / dirname
konstrukcji.mężczyzna basename
źródło
basname(char * path)
a niebasename(const char * path)
), a implementacje, które tego nie robią, wydają się używać bufora statycznego, co czyni je niebezpiecznymi wątkowo (w zasadzie może również zwrócić dynamicznie przydzielane wyniki, ale to uzależnia odalloc
funkcji rodzinnych, co jest niewygodne w C ++).Standardowy C ++ nie zrobi zbyt wiele w tym zakresie, ponieważ nazwy ścieżek są specyficzne dla platformy. Możesz ręcznie przeanalizować ciąg (jak w odpowiedzi glowcodera), skorzystać z udogodnień systemu operacyjnego (np. Http://msdn.microsoft.com/en-us/library/aa364232(v=VS.85).aspx ) lub prawdopodobnie Najlepszym podejściem jest użycie biblioteki systemu plików innej firmy, takiej jak boost :: filesystem.
źródło
Po prostu użyj tego: ExtractFilePath (your_path_file_name)
źródło