Get a file name from a path

前端 未结 21 1426
面向向阳花
面向向阳花 2020-11-30 23:55

What is the simplest way to get the file name that from a path?

string filename = \"C:\\\\MyDirectory\\\\MyFile.bat\"

In this example, I s

相关标签:
21条回答
  • 2020-12-01 00:29

    The task is fairly simple as the base filename is just the part of the string starting at the last delimeter for folders:

    std::string base_filename = path.substr(path.find_last_of("/\\") + 1)
    

    If the extension is to be removed as well the only thing to do is find the last . and take a substr to this point

    std::string::size_type const p(base_filename.find_last_of('.'));
    std::string file_without_extension = base_filename.substr(0, p);
    

    Perhaps there should be a check to cope with files solely consisting of extensions (ie .bashrc...)

    If you split this up into seperate functions you're flexible to reuse the single tasks:

    template<class T>
    T base_name(T const & path, T const & delims = "/\\")
    {
      return path.substr(path.find_last_of(delims) + 1);
    }
    template<class T>
    T remove_extension(T const & filename)
    {
      typename T::size_type const p(filename.find_last_of('.'));
      return p > 0 && p != T::npos ? filename.substr(0, p) : filename;
    }
    

    The code is templated to be able to use it with different std::basic_string instances (i.e. std::string & std::wstring...)

    The downside of the templation is the requirement to specify the template parameter if a const char * is passed to the functions.

    So you could either:

    A) Use only std::string instead of templating the code

    std::string base_name(std::string const & path)
    {
      return path.substr(path.find_last_of("/\\") + 1);
    }
    

    B) Provide wrapping function using std::string (as intermediates which will likely be inlined / optimized away)

    inline std::string string_base_name(std::string const & path)
    {
      return base_name(path);
    }
    

    C) Specify the template parameter when calling with const char *.

    std::string base = base_name<std::string>("some/path/file.ext");
    

    Result

    std::string filepath = "C:\\MyDirectory\\MyFile.bat";
    std::cout << remove_extension(base_name(filepath)) << std::endl;
    

    Prints

    MyFile
    
    0 讨论(0)
  • 2020-12-01 00:29

    A slow but straight forward regex solution:

        std::string file = std::regex_replace(path, std::regex("(.*\\/)|(\\..*)"), "");
    
    0 讨论(0)
  • 2020-12-01 00:30

    This should work too :

    // strPath = "C:\\Dir\\File.bat" for example
    std::string getFileName(const std::string& strPath)
    {
        size_t iLastSeparator = 0;
        return strPath.substr((iLastSeparator = strPath.find_last_of("\\")) != std::string::npos ? iLastSeparator + 1 : 0, strPath.size() - strPath.find_last_of("."));
    }
    

    If you can use it, Qt provide QString (with split, trim etc), QFile, QPath, QFileInfo etc to manipulate files, filenames and directories. And of course it's also cross plaftorm.

    0 讨论(0)
  • 2020-12-01 00:31

    You can use the std::filesystem to do it quite nicely:

    #include <filesystem>
    namespace fs = std::experimental::filesystem;
    
    fs::path myFilePath("C:\\MyDirectory\\MyFile.bat");
    fs::path filename = myFilePath.stem();
    
    0 讨论(0)
  • 2020-12-01 00:33

    If you can use 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();
    

    This is all.

    I recommend you to use boost library. Boost gives you a lot of conveniences when you work with C++. It supports almost all platforms. If you use Ubuntu, you can install boost library by only one line sudo apt-get install libboost-all-dev (ref. How to Install boost on Ubuntu?)

    0 讨论(0)
  • 2020-12-01 00:34

    For long time I was looking for a function able to properly decompose file path. For me this code is working perfectly for both Linux and Windows.

    void decomposePath(const char *filePath, char *fileDir, char *fileName, char *fileExt)
    {
        #if defined _WIN32
            const char *lastSeparator = strrchr(filePath, '\\');
        #else
            const char *lastSeparator = strrchr(filePath, '/');
        #endif
    
        const char *lastDot = strrchr(filePath, '.');
        const char *endOfPath = filePath + strlen(filePath);
        const char *startOfName = lastSeparator ? lastSeparator + 1 : filePath;
        const char *startOfExt = lastDot > startOfName ? lastDot : endOfPath;
    
        if(fileDir)
            _snprintf(fileDir, MAX_PATH, "%.*s", startOfName - filePath, filePath);
    
        if(fileName)
            _snprintf(fileName, MAX_PATH, "%.*s", startOfExt - startOfName, startOfName);
    
        if(fileExt)
            _snprintf(fileExt, MAX_PATH, "%s", startOfExt);
    }
    

    Example results are:

    []
      fileDir:  ''
      fileName: ''
      fileExt:  ''
    
    [.htaccess]
      fileDir:  ''
      fileName: '.htaccess'
      fileExt:  ''
    
    [a.exe]
      fileDir:  ''
      fileName: 'a'
      fileExt:  '.exe'
    
    [a\b.c]
      fileDir:  'a\'
      fileName: 'b'
      fileExt:  '.c'
    
    [git-archive]
      fileDir:  ''
      fileName: 'git-archive'
      fileExt:  ''
    
    [git-archive.exe]
      fileDir:  ''
      fileName: 'git-archive'
      fileExt:  '.exe'
    
    [D:\Git\mingw64\libexec\git-core\.htaccess]
      fileDir:  'D:\Git\mingw64\libexec\git-core\'
      fileName: '.htaccess'
      fileExt:  ''
    
    [D:\Git\mingw64\libexec\git-core\a.exe]
      fileDir:  'D:\Git\mingw64\libexec\git-core\'
      fileName: 'a'
      fileExt:  '.exe'
    
    [D:\Git\mingw64\libexec\git-core\git-archive.exe]
      fileDir:  'D:\Git\mingw64\libexec\git-core\'
      fileName: 'git-archive'
      fileExt:  '.exe'
    
    [D:\Git\mingw64\libexec\git.core\git-archive.exe]
      fileDir:  'D:\Git\mingw64\libexec\git.core\'
      fileName: 'git-archive'
      fileExt:  '.exe'
    
    [D:\Git\mingw64\libexec\git-core\git-archiveexe]
      fileDir:  'D:\Git\mingw64\libexec\git-core\'
      fileName: 'git-archiveexe'
      fileExt:  ''
    
    [D:\Git\mingw64\libexec\git.core\git-archiveexe]
      fileDir:  'D:\Git\mingw64\libexec\git.core\'
      fileName: 'git-archiveexe'
      fileExt:  ''
    

    I hope this helps you also :)

    0 讨论(0)
提交回复
热议问题