Получение имени каталога с именем
У меня есть имя файла (C:folderfoo.txt) и мне нужно получить имя папки (C:folder) в неуправляемом C++. В C# я бы сделал что-то вроде этого:
string folder = new FileInfo("C:folderfoo.txt").DirectoryName;
есть ли функция, которая может быть использована в неуправляемом C++ для извлечения пути из имени файла?
11 ответов:
для этого есть стандартная функция Windows, PathRemoveFileSpec. Если вы поддерживаете только Windows 8 и более поздние версии, настоятельно рекомендуется использовать PathCchRemoveFileSpec. Среди других улучшений, он больше не ограничивается
MAX_PATH
(260) символов.
С Помощью Boost.Файловая система:
boost::filesystem::path p("C:\folder\foo.txt"); boost::filesystem::path dir = p.parent_path();
пример из 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; }
согласно cppreference.com, поддержка экспериментальной библиотеки заголовков существует для C++17 / 1z с классом
std::experimental::filesystem::path
методом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'; }
возможный выход:
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"
почему это должно быть так сложно?
#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 }
использовать boost::файловая система. Он будет включен в следующий стандарт в любом случае, так что вы можете также привыкнуть к нему.
_splitpath - это хорошее решение ЭЛТ.
Я так удивлен, что никто не упомянул стандартный способ в Posix
пожалуйста, используйте
basename / dirname
конструктов.man basename
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()
получить имя родительской папки.
стандартный C++ не будет делать много для вас в этом отношении, так как имена путей зависят от платформы. Вы можете вручную разобрать строку (как в ответе glowcoder), использовать средства операционной системы (например,http://msdn.microsoft.com/en-us/library/aa364232 (v=VS.85).aspx ), или, вероятно, лучший подход, вы можете использовать стороннюю библиотеку файловой системы, такую как boost::filesystem.