在C++编程中,处理文件路径和文件名是每个开发者都会遇到的常见任务✨🔍。然而,要从复杂的路径中提取出纯粹的文件名,并且去除扩展名,往往需要掌握一些实用的技巧和方法🛠️💡。如果你正在寻找快速、高效的解决方案,这篇文章将为你提供多种C++实现方式,从基础的字符串操作到强大的C++17的
filesystem
库,帮你轻松搞定文件路径解析🚀📂。无论你是初学者还是经验丰富的开发者,都能从中获得实用的代码示例和详细的解释📚👨💻👩💻,迅速提升你的编程效率⚡!
赶快点赞👍、收藏📌,关注我们🎯,不错过更多实用的编程技巧与深度分析🎉💬!
本文详细介绍了在C++程序中获取文件名的多种方式。
还会介绍如何在需要时移除文件扩展名。
一.在C++中从路径获取文件名
从文件路径中获取文件名是一个简单的任务。
程序需要找到最后一个分隔符,并删除它之前的所有内容。
如果需要移除扩展名,程序会搜索一个点(.
),并删除它之后的所有内容。
我们来看看一些实战案例,了解如何从路径中获取文件名。
1.1.使用 find_last_of
和 substr
方法
为了从路径中获取文件名,程序使用了两个方法——clear_slash()
来查找分隔符,extension_removal()
来移除扩展名。
示例代码:
#include <string>
#include<iostream>
using namespace std;
// clear_slash 方法:从文件路径中提取文件名(包括扩展名)
string clear_slash(string const& path_of_file, string const& d_slash = "/\\")
{
// 找到路径中最后一个分隔符的位置
size_t index_of_slash = path_of_file.find_last_of(d_slash);
// 使用 substr 方法提取从最后一个分隔符之后的子字符串,即文件名
string file_name = path_of_file.substr(index_of_slash + 1);
return file_name;
}
// extension_removal 方法:从文件名中去掉扩展名
string extension_removal(string const& name_of_file)
{
// 找到最后一个点(扩展名的标志)
size_t index_of_period = name_of_file.find_last_of('.');
// 提取点之前的部分,即文件名(不包括扩展名)
string file_without_extension = name_of_file.substr(0, index_of_period);
return file_without_extension;
}
int main() {
// 定义文件路径
string file_address = "C:\\Users\\Win 10\\Documents\\get_filename.md";
// 输出带扩展名的文件名
cout << "Filename With extension = " << clear_slash(file_address) << endl;
// 输出不带扩展名的文件名
cout << "Just the Filename = " << extension_removal(clear_slash(file_address)) << endl;
}
输出结果:
Filename With extension = get_filename.md
Just the Filename = get_filename
让我们解析一下上述代码:
前两行代码导入了程序所需的依赖库——string
和 iostream
。在第三行,包含了 std
的作用域,这意味着可以直接使用 string
等数据类型,而无需使用 std::string
这样的前缀。
clear_slash()
方法:
// 定义 clear_slash 方法,接受文件路径 path_of_file 和分隔符 d_slash(默认为 "/\\")
string clear_slash(string const& path_of_file, string const& d_slash = "/\\")
{
// 使用 find_last_of 找到文件路径中最后一个分隔符的位置,返回其索引
size_t index_of_slash = path_of_file.find_last_of(d_slash);
// 使用 substr 从最后一个分隔符后提取子字符串(即文件名)
string file_name = path_of_file.substr(index_of_slash + 1);
// 返回提取的文件名
return file_name;
}
上述代码片段创建一个名为 clear_slash
的字符串方法,接受两个字符串参数——path_of_file
用于存储文件路径,d_slash
用于表示分隔符。变量 d_slash
被初始化为 '/\\'
,即双反斜杠。
该方法的功能是从文件路径中提取文件名。它通过查找文件路径中的最后一个分隔符 \\
来实现,并删除分隔符之前的所有内容。
为了找到最后一个分隔符的索引,使用了 find_last_of()
函数。
语法 path_of_file.find_last_of(d_slash)
会使用 d_slash
的值,在 path_of_file
变量中搜索最后一次出现的分隔符。它返回最后一个双反斜杠的索引,并将其存储在类型为 size_t
的变量 index_of_slash
中。
substr()
函数用于从给定字符串中提取子字符串。语法 path_of_file.substr(index_of_slash + 1)
会返回从 path_of_file
变量中从 \\
索引之后的子字符串,并将其存储在新的字符串变量 file_name
中。
最后,返回变量 file_name
。
extension_removal()
方法
第二个方法用于从文件路径中移除扩展名。extension_removal
是一个字符串方法,接受一个字符串变量 name_of_file
作为参数,该方法会获取传入的文件名,并返回不带扩展名的文件名。
// 定义 extension_removal 方法,接受一个字符串参数 name_of_file,表示文件名
string extension_removal(string const& name_of_file)
{
// 使用 find_last_of 查找文件名中最后一个点(.)的位置,即扩展名的开始位置
size_t index_of_period = name_of_file.find_last_of('.');
// 使用 substr 从文件名的开头提取子字符串,直到点的位置(不包括扩展名)
string file_without_extension = name_of_file.substr(0, index_of_period);
// 返回移除扩展名后的文件名
return file_without_extension;
}
移除扩展名的过程类似于移除分隔符。首先,创建一个名为 index_of_period
的变量,类型为 size_t
,它存储了通过 find_last_of()
函数从 name_of_file
中查找到的最后一个点(.
)的位置。
然后,使用 substr
函数将点(.
)之前的部分提取出来,保存到一个新的字符串变量 file_without_extension
中,从索引 0 开始,到 index_of_period
位置为止。
最后,返回变量 file_without_extension
。现在,我们来看一下如何使用这两个方法从路径中获取文件名。
main方法
// 定义主函数
int main() {
// 定义文件路径字符串变量 file_address,包含文件的完整路径
string file_address = "C:\\Users\\Win 10\\Documents\\get_filename.md";
// 调用 clear_slash 方法,提取文件路径中的文件名(包括扩展名),并输出结果
cout << "Filename With extension = " << clear_slash(file_address) << endl;
// 调用 extension_removal 方法,移除文件名中的扩展名后再输出
cout << "Just the Filename = " << extension_removal(clear_slash(file_address)) << endl;
}
文件路径存储在变量 file_address
中。在第二行,clear_slash()
方法使用 file_address
传递文件路径,分离路径,并打印返回的值。
为了同时从文件路径中移除扩展名,两个方法被嵌套调用,file_address
被作为参数传递。这样只返回文件名,并将其打印出来。
1.2.使用模板(Templates)
当使用不同类型的字符串实例时,例如 string
或 wstring
(比基本字符串更宽的字符串),可以使用模板来从路径中获取文件名。
#include <string>
#include<iostream>
using namespace std;
// 模板方法:从文件路径中提取文件名(包括扩展名)
template<class T>
T remove_slash(T const& path_of_file, T const& d_slash = "/\\")
{
size_t index_of_slash = path_of_file.find_last_of(d_slash);
string file_name = path_of_file.substr(index_of_slash + 1);
return file_name;
}
// 模板方法:从文件名中移除扩展名
template<class T>
T extension_removal(T const& name_of_file)
{
typename T::size_type const period_index(name_of_file.find_last_of('.'));
string filename = name_of_file.substr(0, period_index);
return filename;
}
int main() {
// 使用 remove_slash 和 extension_removal 提取和移除扩展名
string filepath1 = remove_slash<std::string>("C:\\Users\\Win 10\\Documents\\get_filename.md");
string filepath2 = extension_removal<std::string>("C:\\Users\\Win 10\\Documents\\get_filename.md");
cout << remove_slash(filepath1) << endl; // 输出带扩展名的文件名
cout << extension_removal(filepath2) << endl; // 输出去除扩展名后的文件名
cout << extension_removal(remove_slash(filepath1)) << endl; // 嵌套使用:输出不带扩展名的文件名
}
输出结果:
get_filename.md
C:\Users\Win 10\Documents\get_filename
get_filename
代码解析如下:
导入的包与上一个程序相同。
定义了一个模板类 T
。第一个方法 remove_slash
使用 T
作为数据类型创建。它有两个参数——path_of_file
和 d_slash
,数据类型为 T
。
第二个方法 extension_removal
也使用数据类型 T
,并且有一个参数 name_of_file
。
在主函数中,字符串变量 filepath1
存储了文件地址,并使用 remove_slash
作为标识。同样,filepath2
存储了文件地址,并使用 extension_removal
作为标识。
第一个方法 remove_slash
被调用,filepath1
作为参数传递,并打印返回的值。然后,调用 extension_removal
方法,filepath2
作为参数传递。在嵌套的方法中,可以使用这两个文件路径变量。
这个例子同样可以与其他专门的字符串类型一起使用,例如 wstring
,以从路径中获取文件名。
1.3.使用 filesystem
库(C++17 及以上)
如果系统支持 C++17 或更高版本,最简单的方法是使用 filesystem
库来获取文件名。
filesystem
库通过命名空间被分配给一个关键字 obj
。
为了获取文件名,使用了两个函数:
filename()
– 返回带扩展名的文件名。stem()
– 仅返回文件名,不带扩展名。
假设一个变量 filename
包含文件路径,如 "C:\MyDirectory\MyFile.bat"。要从路径中获取文件名,可以使用以下语法:
// 定义一个字符串变量 filename,包含文件的完整路径
std::string filename = "C:\\MyDirectory\\MyFile.bat";
// 使用 filesystem 库中的 path 类创建一个路径对象,并调用 filename() 函数获取带扩展名的文件名
// 输出该文件名并换行
std::cout << fs::path(filename).filename() << '\n';
这将返回 — "MyFile.bat"。
如果也要移除扩展名,可以使用以下代码,代码中用stem
方法:
std::cout << fs::path(filename).stem();
这将返回 — "MyFile"
二.综合实战
下面的程序有三个导入:iostream
、string
和 filesystem
库,它使用一组输入来查看文件系统函数对于特定输入返回的结果:
#include <iostream>
#include <string>
#include <filesystem>
namespace obj = std::filesystem;
using namespace std;
int main()
{
// 方法 1:使用 filesystem 库
string file_address = "C:\\Users\\Win 10\\Pictures\\pic1.jpg";
cout << obj::path(file_address).filename() << "\n" << endl; // 输出带扩展名的文件名
cout << obj::path(file_address).stem() << "\n" << endl; // 输出不带扩展名的文件名
// 方法 2:使用其他文件路径
cout << obj::path("C:/Users/Win 10/AppData/app.exe").filename() << "\n" << endl;
cout << obj::path("C:/Users/Win 10/AppData/app.exe").stem() << "\n" << endl;
}
输出结果:
pic1.jpg
pic1
app.exe
app
代码解析:
-
filesystem
库: 引入filesystem
库,并使用obj
作为其命名空间别名。 -
filename()
方法: 返回包含扩展名的文件名。 -
stem()
方法: 返回不包含扩展名的文件名。
三.总结
本文详细介绍了在 C++ 中从文件路径提取文件名的多种方法,从基础的字符串操作到使用现代 C++17 中的 filesystem
库,涵盖了多种解决方案🌟。我们深入探讨了如何使用 find_last_of
和 substr
方法来分割路径并提取文件名,进一步探讨了如何通过移除扩展名来获得纯粹的文件名🎯。除此之外,文章还介绍了模板方法,适用于不同类型的字符串(如 string
和 wstring
),以及如何灵活应对不同的字符串需求🔧。
无论你是初学者,还是经验丰富的开发者,这些技巧都能帮助你更高效地处理文件路径解析的问题🚀💡。通过这些方法,你将能够在 C++ 项目中轻松应对文件路径的各种操作📂✨。
如果你觉得这篇文章对你有帮助,别忘了 点赞 👍,收藏 📌,并 关注 🔔 我们,获取更多实用的编程技巧与深入分析!如果你有任何疑问或想法,欢迎在 评论区留言 💬,和我们一起讨论交流,提升编程技能👨💻👩💻!我们期待与你的互动,共同进步🌱🎉。