Quelle est la façon la plus simple d'obtenir le nom du fichier à partir d'un chemin ?
string filename = "C:\\MyDirectory\\MyFile.bat"
Dans cet exemple, je devrais obtenir "MonFichier". sans extension.
Quelle est la façon la plus simple d'obtenir le nom du fichier à partir d'un chemin ?
string filename = "C:\\MyDirectory\\MyFile.bat"
Dans cet exemple, je devrais obtenir "MonFichier". sans extension.
Si vous pouvez utiliser le boost,
#include <boost/filesystem.hpp>
path p("C:\\MyDirectory\\MyFile.bat");
string basename = p.filename().string();
//or
//string basename = path("C:\\MyDirectory\\MyFile.bat").filename().string();
C'est tout.
Je vous recommande d'utiliser la bibliothèque Boost. Boost vous donne beaucoup de commodités lorsque vous travaillez avec C++. Elle supporte presque toutes les plateformes. Si vous utilisez Ubuntu, vous pouvez installer la bibliothèque boost en une seule ligne sudo apt-get install libboost-all-dev
(réf. Comment installer boost sur Ubuntu ? )
Vous pouvez également utiliser les API shell PathFindFileName, PathRemoveExtension. C'est probablement pire que _splitpath pour ce problème particulier, mais ces API sont très utiles pour toutes sortes de tâches d'analyse des chemins et elles prennent en compte les chemins UNC, les slashs avant et d'autres choses bizarres.
wstring filename = L"C:\\MyDirectory\\MyFile.bat";
wchar_t* filepart = PathFindFileName(filename.c_str());
PathRemoveExtension(filepart);
http://msdn.microsoft.com/en-us/library/Windows/desktop/bb773589(v=vs.85).aspx
L'inconvénient est que vous devez créer un lien vers shlwapi.lib, mais je ne sais pas vraiment pourquoi c'est un inconvénient.
Fonction :
#include <string>
std::string
basename(const std::string &filename)
{
if (filename.empty()) {
return {};
}
auto len = filename.length();
auto index = filename.find_last_of("/\\");
if (index == std::string::npos) {
return filename;
}
if (index + 1 >= len) {
len--;
index = filename.substr(0, len).find_last_of("/\\");
if (len == 0) {
return filename;
}
if (index == 0) {
return filename.substr(1, len - 1);
}
if (index == std::string::npos) {
return filename.substr(0, len);
}
return filename.substr(index + 1, len - index - 1);
}
return filename.substr(index + 1, len - index);
}
Tests :
#define CATCH_CONFIG_MAIN
#include <catch/catch.hpp>
TEST_CASE("basename")
{
CHECK(basename("") == "");
CHECK(basename("no_path") == "no_path");
CHECK(basename("with.ext") == "with.ext");
CHECK(basename("/no_filename/") == "no_filename");
CHECK(basename("no_filename/") == "no_filename");
CHECK(basename("/no/filename/") == "filename");
CHECK(basename("/absolute/file.ext") == "file.ext");
CHECK(basename("../relative/file.ext") == "file.ext");
CHECK(basename("/") == "/");
CHECK(basename("c:\\windows\\path.ext") == "path.ext");
CHECK(basename("c:\\windows\\no_filename\\") == "no_filename");
}
Extrait de C++ Docs - string::find_last_of
#include <iostream> // std::cout
#include <string> // std::string
void SplitFilename (const std::string& str) {
std::cout << "Splitting: " << str << '\n';
unsigned found = str.find_last_of("/\\");
std::cout << " path: " << str.substr(0,found) << '\n';
std::cout << " file: " << str.substr(found+1) << '\n';
}
int main () {
std::string str1 ("/usr/bin/man");
std::string str2 ("c:\\windows\\winhelp.exe");
SplitFilename (str1);
SplitFilename (str2);
return 0;
}
Sorties :
Splitting: /usr/bin/man
path: /usr/bin
file: man
Splitting: c:\windows\winhelp.exe
path: c:\windows
file: winhelp.exe
Variante C++11 (inspirée de la version de James Kanze) avec initialisation uniforme et lambda anonyme en ligne.
std::string basename(const std::string& pathname)
{
return {std::find_if(pathname.rbegin(), pathname.rend(),
[](char c) { return c == '/'; }).base(),
pathname.end()};
}
Il ne supprime cependant pas l'extension du fichier.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
2 votes
Rechercher à partir de l'arrière jusqu'à ce que vous frappiez un retour arrière ?
2 votes
@KerrekSB, vous voulez dire barre oblique inversée ;)
0 votes
J'ai un std::string qui contient le chemin d'un fichier "c : \\MyDirectory\\Myfile.pdf "Je dois renommer ce fichier en monfichier_md.pdf et je dois donc obtenir le nom du fichier à partir du chemin.
1 votes
Si vous devez faire beaucoup de travail avec les chemins de fichiers, pensez à utiliser Boost FileSystem. boost.org/doc/libs/release/libs/filesystem/v3/doc/index.htm
2 votes
@Nim : Oui ! J'ai dû perdre le fil...