C++文件路径处理2 - 路径拼接&路径解析
1. 关键词
关键词:
C++ 文件路径处理 路径拼接 获取父目录的路径 获取文件名 获取拓展名 跨平台
应用场景:
- 路径的拼接
- 路径的解析
2. filesystem.h
#pragma once #include <string> #include <iostream> #include <cstdio> #include "filetype.h" namespace cutl { /** * @brief The class for file path operations. * */ class filepath { public: /** * @brief Construct a new filepath object * * @param path file path string */ filepath(const std::string &path); /** * @brief Construct a new filepath object by copy * * @param other other filepath object */ filepath(const filepath &other); /** * @brief Assign operator, assign a new filepath object by copy * * @param other other filepath object * @return filepath& the reference of the current filepath object */ filepath &operator=(const filepath &other); /** * @brief Destroy the filepath object * */ ~filepath() = default; public: /** * @brief Get the path separator of the current os platform. * * @return the path separator */ static char separator(); /** * @brief Get the string of the filepath. * * @return the filepath */ std::string str() const; /** * @brief Join the current filepath with a new filename. * * @param filename the filename to be joined * @return the new filepath object */ filepath join(const std::string &filename) const; /** * @brief Get the parent directory of the filepath. * * @return parent directory path */ std::string dirname() const; /** * @brief Get the filename or directory name of the filepath. * * @return filename or directory name */ std::string basename() const; /** * @brief Get the extension of the filepath. * * @return extension with dot */ std::string extension() const; private: std::string filepath_; }; /** * @brief Define the output stream operator for filepath object. * * @param os the std::ostream object * @param fp the filepath object to be output * @return std::ostream& the reference of the std::ostream object after outputing the filepath object. */ std::ostream &operator<<(std::ostream &os, const filepath &fp); /** * @brief Create a filepath object from a string. * * @param path file path string * @return filepath object */ filepath path(const std::string &path); } // namespace cutl
3. filepath.cpp
#include "filepath.h" #include "inner/logger.h" #include "inner/filesystem.h" #include "strutil.h" #include "sysutil.h" namespace cutl { static constexpr char win_separator = '\\'; static constexpr char unix_separator = '/'; void fixpath(std::string &path) { if (win_separator == filepath::separator()) { for (size_t i = 0; i < path.size(); i++) { if (path[i] == unix_separator) { path[i] = win_separator; } } } else if (unix_separator == filepath::separator()) { for (size_t i = 0; i < path.size(); i++) { if (path[i] == win_separator) { path[i] = unix_separator; } } } else { // do nothing } while (path.empty() || path.back() == filepath::separator()) { path.pop_back(); } } filepath::filepath(const std::string &path) { filepath_ = path; fixpath(filepath_); } filepath::filepath(const filepath &other) { filepath_ = other.filepath_; } filepath &filepath::operator=(const filepath &other) { this->filepath_ = other.filepath_; return *this; } char filepath::separator() { #if defined(_WIN32) || defined(__WIN32__) return win_separator; #else return unix_separator; #endif } std::string filepath::str() const { return filepath_; } filepath filepath::join(const std::string &filename) const { std::string path = filepath_ + separator() + filename; return filepath(path); } std::string filepath::dirname() const { auto index = filepath_.find_last_of(separator()); if (index == std::string::npos) { return ""; } return filepath_.substr(0, index); } std::string filepath::basename() const { auto index = filepath_.find_last_of(separator()); // auto len = filepath_.length() - index - 1; if (index == std::string::npos) { return filepath_; } return filepath_.substr(index + 1); } std::string filepath::extension() const { auto pos = filepath_.find_last_of('.'); if (pos == std::string::npos) { return ""; } return filepath_.substr(pos); } std::ostream &operator<<(std::ostream &os, const filepath &fp) { os << fp.str(); return os; } filepath path(const std::string &path) { return filepath(path); } } // namespace cutl
6. 测试代码
#include "common.hpp" #include "fileutil.h" void TestJoin() { PrintSubTitle("TestJoin"); auto path1 = cutl::path("/Users/spencer/workspace/common_util/src/usage_demo"); auto path2 = path1.join("filepath.hpp"); std::cout << "path1: " << path1 << std::endl; std::cout << "path2: " << path2 << std::endl; } void TestDirnameBasename() { PrintSubTitle("TestDirnameBasename"); auto path1 = cutl::path("/Users/spencer/workspace/common_util/src/usage_demo/filepath.hpp"); std::cout << "path1: " << path1 << std::endl; std::cout << "dirname: " << path1.dirname() << std::endl; std::cout << "basename: " << path1.basename() << std::endl; auto path2 = cutl::path("/Users/spencer/workspace/common_util/src/usage_demo"); std::cout << "path2: " << path2 << std::endl; std::cout << "dirname: " << path2.dirname() << std::endl; std::cout << "basename: " << path2.basename() << std::endl; auto path3 = cutl::path("filepath.hpp"); std::cout << "path3: " << path3 << std::endl; std::cout << "dirname: " << path3.dirname() << std::endl; std::cout << "basename: " << path3.basename() << std::endl; } void TestExtenstion() { PrintSubTitle("TestExtenstion"); auto path1 = cutl::path("/Users/spencer/workspace/common_util/src/usage_demo/filepath.hpp"); std::cout << "path1: " << path1 << ", extension: " << path1.extension() << std::endl; auto path2 = cutl::path("/Users/spencer/workspace/common_util/src/usage_demo/filepath"); std::cout << "path2: " << path2 << ", extension: " << path2.extension() << std::endl; }
7. 运行结果
----------------------------------------------TestJoin---------------------------------------------- path1: /Users/spencer/workspace/common_util/src/usage_demo path2: /Users/spencer/workspace/common_util/src/usage_demo/filepath.hpp ----------------------------------------TestDirnameBasename----------------------------------------- path1: /Users/spencer/workspace/common_util/src/usage_demo/filepath.hpp dirname: /Users/spencer/workspace/common_util/src/usage_demo basename: filepath.hpp path2: /Users/spencer/workspace/common_util/src/usage_demo dirname: /Users/spencer/workspace/common_util/src basename: usage_demo path3: filepath.hpp dirname: basename: filepath.hpp -------------------------------------------TestExtenstion------------------------------------------- path1: /Users/spencer/workspace/common_util/src/usage_demo/filepath.hpp, extension: .hpp path2: /Users/spencer/workspace/common_util/src/usage_demo/filepath, extension:
8. 源码地址
更多详细代码,请查看本人写的C++ 通用工具库: common_util, 本项目已开源,代码简洁,且有详细的文档和Demo。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战