Get a file name from a path

前端 未结 21 1636
面向向阳花
面向向阳花 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
    T base_name(T const & path, T const & delims = "/\\")
    {
      return path.substr(path.find_last_of(delims) + 1);
    }
    template
    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("some/path/file.ext");
    

    Result

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

    Prints

    MyFile
    

提交回复
热议问题