J'ai un nom de fichier (C:\folder\foo.txt) et j'ai besoin de récupérer le nom du dossier (C:\folder) en C++ non géré. En C #, je ferais quelque chose comme ça:
string folder = new FileInfo("C:\folder\foo.txt").DirectoryName;
Existe-t-il une fonction utilisable dans C++ non géré pour extraire le chemin d'accès du nom de fichier?
Il existe une fonction Windows standard pour cela, PathRemoveFileSpec . Si vous ne prenez en charge que Windows 8 et les versions ultérieures, il est vivement recommandé d'utiliser PathCchRemoveFileSpec . Parmi d'autres améliorations, il n'est plus limité à MAX_PATH
_ (260) caractères.
Utilisation de Boost.Filesystem:
boost::filesystem::path p("C:\\folder\\foo.txt");
boost::filesystem::path dir = p.parent_path();
Exemple tiré de 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;
}
En C++ 17, il existe une classe std::filesystem::path
en utilisant la méthode 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';
}
Sortie possible:
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"
Pourquoi cela doit-il être si compliqué?
#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
}
Utilisez boost :: système de fichiers. De toute façon, il sera intégré à la prochaine norme afin que vous puissiez aussi vous y habituer.
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
Vous aurez peut-être besoin de p.parent_path().filename()
pour obtenir le nom du dossier parent.
_ splitpath est une solution CRT de Nice.
Je suis tellement surpris que personne n'ait mentionné la méthode standard dans Posix
Veuillez utiliser basename / dirname
construit.
homme basename