任务相当简单,因为基本文件名只是从文件夹的最后一个分隔符开始的字符串的一部分:
std::string base_filename = path.substr(path.find_last_of("/\\") + 1)
如果要删除扩展名,唯一要做的就是找到最后一个 . 并使用 substr 到这一点
std::string::size_type const p(base_filename.find_last_of('.'));
std::string file_without_extension = base_filename.substr(0, p);
也许应该检查以处理仅包含扩展名的文件(即.bashrc...)
如果您将其拆分为单独的功能,您可以灵活地重用单个任务:
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;
}
代码经过模板化,可以与不同的std::basic_string 实例一起使用(即std::string 和std::wstring...)
模板的缺点是如果将const char * 传递给函数,则需要指定模板参数。
所以你可以:
A) 仅使用 std::string 而不是模板代码
std::string base_name(std::string const & path)
{
return path.substr(path.find_last_of("/\\") + 1);
}
B) 使用std::string 提供包装函数(作为可能被内联/优化掉的中间体)
inline std::string string_base_name(std::string const & path)
{
return base_name(path);
}
C) 使用const char *调用时指定模板参数。
std::string base = base_name<std::string>("some/path/file.ext");
结果
std::string filepath = "C:\\MyDirectory\\MyFile.bat";
std::cout << remove_extension(base_name(filepath)) << std::endl;
打印
MyFile