首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 從絕對路徑提取帶後綴文件名:標準庫 filesystem 最佳實踐與手動解析對比

     編輯:程式設計疑難解答

現代 C++ (C++17) 標準解法:std::filesystem

C++17 引入 <filesystem> 標準庫,提供跨平台、類型安全的路徑操作,是**首選方案**。

#include <iostream>
#include <filesystem>
#include <string>

namespace fs = std::filesystem;

int main() {
    std::string path = "c:\\new\\music.mp3"; // Windows 路徑需轉義或用原始字符串
    // std::string path = R"(c:\new\music.mp3)"; // C++11 原始字符串字面量,無需轉義
    
    fs::path p(path);
    std::string filename = p.filename().string(); // 獲取文件名 "music.mp3"
    
    std::cout << "文件名: " << filename << std::endl;
    // 輸出: 文件名: music.mp3
    
    return 0;
}

關鍵優勢

  • 自動處理 Windows (`\`) 和 POSIX (`/`) 路徑分隔符。
  • 正確處理邊界情況:尾部斜槓、相對路徑、UNC 路徑等。
  • 提供豐富操作:parent_path(), extension(), stem() (不帶擴展名文件名) 等。

C++11/14 兼容方案:手動解析 (僅作為理解原理或舊標準環境)

若無法使用 C++17,可手動查找最後一個路徑分隔符:

#include <iostream>
#include <string>

std::string extractFilename(const std::string& path) {
    if (path.empty()) return "";
    
    // 查找最後一個 '/' 或 '\'
    size_t pos = path.find_last_of("/\\");
    
    // npos 表示未找到 (如 "music.mp3" 純文件名),返回整個字符串
    if (pos == std::string::npos) return path;
    
    // 返回分隔符後的子串
    return path.substr(pos + 1);
}

int main() {
    std::string paths[] = {
        "c:\\new\\music.mp3",
        "/home/user/document.pdf",
        "relative/path/image.png",
        "no_slash.txt",
        "trailing_slash/",
        ""
    };
    
    for (const auto& p : paths) {
        std::cout << "路徑: [" << p << "] -> 文件名: [" << extractFilename(p) << "]" << std::endl;
    }
    return 0;
}

輸出結果

路徑: [c:\new\music.mp3] -> 文件名: [music.mp3]
路徑: [/home/user/document.pdf] -> 文件名: [document.pdf]
路徑: [relative/path/image.png] -> 文件名: [image.png]
路徑: [no_slash.txt] -> 文件名: [no_slash.txt]
路徑: [trailing_slash/] -> 文件名: []  (目錄無文件名)
路徑: [] -> 文件名: []

Boost.Filesystem 替代方案 (C++17 前業界標準)

#include <boost/filesystem.hpp>
#include <iostream>
#include <string>

namespace bfs = boost::filesystem;

int main() {
    std::string path = "c:\\new\\music.mp3";
    bfs::path p(path);
    std::cout << p.filename().string() << std::endl; // music.mp3
    return 0;
}

總結建議

  1. C++17+ 環境:直接使用 std::filesystem::path::filename(),最安全、可移植、可維護。
  2. 舊標準環境:封裝 extractFilename 函數處理雙分隔符兼容,注意邊界情況 (目錄路徑、空串)。
  3. 避免 使用固定字符循環查找 (如原答案 `for(int i=str.size()-1...)`),易出現越界、編碼問題且不跨平台。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved