C++实战:从文件路径提取文件名与移除扩展名的多种方法和技巧

在C++编程中,处理文件路径和文件名是每个开发者都会遇到的常见任务✨🔍。然而,要从复杂的路径中提取出纯粹的文件名,并且去除扩展名,往往需要掌握一些实用的技巧和方法🛠️💡。如果你正在寻找快速、高效的解决方案,这篇文章将为你提供多种C++实现方式,从基础的字符串操作到强大的C++17的filesystem库,帮你轻松搞定文件路径解析🚀📂。

无论你是初学者还是经验丰富的开发者,都能从中获得实用的代码示例和详细的解释📚👨‍💻👩‍💻,迅速提升你的编程效率⚡!

赶快点赞👍、收藏📌,关注我们🎯,不错过更多实用的编程技巧与深度分析🎉💬!


本文详细介绍了在C++程序中获取文件名的多种方式。

还会介绍如何在需要时移除文件扩展名。

一.在C++中从路径获取文件名

从文件路径中获取文件名是一个简单的任务。

程序需要找到最后一个分隔符,并删除它之前的所有内容。

如果需要移除扩展名,程序会搜索一个点(.),并删除它之后的所有内容。

我们来看看一些实战案例,了解如何从路径中获取文件名。

1.1.使用 find_last_ofsubstr 方法

为了从路径中获取文件名,程序使用了两个方法——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

让我们解析一下上述代码:

前两行代码导入了程序所需的依赖库——stringiostream。在第三行,包含了 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)

当使用不同类型的字符串实例时,例如 stringwstring(比基本字符串更宽的字符串),可以使用模板来从路径中获取文件名。

#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_filed_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"

二.综合实战

下面的程序有三个导入:iostreamstringfilesystem 库,它使用一组输入来查看文件系统函数对于特定输入返回的结果:

#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

代码解析:

  1. filesystem 库: 引入 filesystem 库,并使用 obj 作为其命名空间别名。

  2. filename() 方法: 返回包含扩展名的文件名。

  3. stem() 方法: 返回不包含扩展名的文件名。

三.总结

本文详细介绍了在 C++ 中从文件路径提取文件名的多种方法,从基础的字符串操作到使用现代 C++17 中的 filesystem 库,涵盖了多种解决方案🌟。我们深入探讨了如何使用 find_last_ofsubstr 方法来分割路径并提取文件名,进一步探讨了如何通过移除扩展名来获得纯粹的文件名🎯。除此之外,文章还介绍了模板方法,适用于不同类型的字符串(如 stringwstring),以及如何灵活应对不同的字符串需求🔧。

无论你是初学者,还是经验丰富的开发者,这些技巧都能帮助你更高效地处理文件路径解析的问题🚀💡。通过这些方法,你将能够在 C++ 项目中轻松应对文件路径的各种操作📂✨。


如果你觉得这篇文章对你有帮助,别忘了 点赞 👍,收藏 📌,并 关注 🔔 我们,获取更多实用的编程技巧与深入分析!如果你有任何疑问或想法,欢迎在 评论区留言 💬,和我们一起讨论交流,提升编程技能👨‍💻👩‍💻!我们期待与你的互动,共同进步🌱🎉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大名顶顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值