首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

檔案副檔名比對:遞迴解析多層副檔名的 C++ 實作

     編輯:關於C語言

實務中常遇到 file.tar.gz、setup.exe.config 等多層副檔名,需提取最內層(最右側)副檔名進行類型判斷。本文提供基於 MFC CString 的遞迴解析方案,並給出標準 C++ 替代實作。

MFC 版本(原文改良)


#include <afx.h>
#include <iostream>
#include <string>

CString GetExtName(CString fileName) {
    int pos = fileName.Find(_T('.'));
    if (pos == -1) return fileName;           // 無點號,視整串為副檔名
    CString rest = fileName.Mid(pos + 1);
    return GetExtName(rest);                  // 遞迴處理剩餘部分
}

int main() {
    std::string input;
    while (std::cout << "輸入: " && std::cin >> input) {
        CString fname(input.c_str());
        CString ext = GetExtName(fname);
        ext.MakeLower();                      // 大小寫不敏感比對
        
        if (ext == _T("txt"))       std::cout << "輸出: txt\n";
        else if (ext == _T("wmv"))  std::cout << "輸出: wmv\n";
        else if (ext == _T("exe"))  std::cout << "輸出: exe\n";
        else                        std::cout << "輸出: 未知(" << (LPCTSTR)ext << ")\n";
    }
    return 0;
}

測試案例

輸入遞迴過程輸出
11.exeexeexe
11.exe.wmvexe.wmv → wmvwmv
111.exe.wmv.txtexe.wmv.txt → wmv.txt → txttxt
READMEREADME未知(README)
.gitignoregitignore未知(gitignore)

標準 C++17 替代方案(跨平台、無 MFC 依賴)


#include <string>
#include <string_view>
#include <algorithm>
#include <cctype>

std::string get_extension(std::string_view filename) {
    // 找最後一個點號
    auto pos = filename.find_last_of('.');
    if (pos == std::string_view::npos) return std::string(filename);
    if (pos == filename.length() - 1) return "";  // 以點結尾
    return std::string(filename.substr(pos + 1));
}

std::string to_lower(std::string s) {
    std::transform(s.begin(), s.end(), s.begin(),
                   [](unsigned char c){ return std::tolower(c); });
    return s;
}

int main() {
    std::string input;
    while (std::cout << "輸入: " && std::cin >> input) {
        std::string ext = to_lower(get_extension(input));
        if (ext == "txt")      std::cout << "輸出: txt\n";
        else if (ext == "wmv") std::cout << "輸出: wmv\n";
        else if (ext == "exe") std::cout << "輸出: exe\n";
        else                   std::cout << "輸出: 未知(" << ext << ")\n";
    }
}

關鍵差異比較

特性MFC 遞迴版標準 C++ 版
相依性需 MFC/ATL僅標準庫
演算法遞迴找第一個點單次掃描找最後一個點
效能O(k) 遞迴深度O(n) 單次遍歷
跨平台Windows only全平台
處理 .hidden回傳 "hidden"回傳 "hidden"
處理 file.回傳 ""回傳 ""

工程建議

  1. 優先用標準庫:std::filesystem::path (C++17) 提供 .extension() 直接取得含點號的副檔名
  2. 大小寫正規化:Windows 不區分大小寫,Linux 區分,比對前統一轉小寫
  3. 白名單機制:用 unordered_set<string> 存儲允許的副檔名,O(1) 查找
  4. 安全考量:file.exe.jpg 可能偽裝圖片,伺服器端應檢查 Magic Number 而非單信副檔名

總結

遞迴解析雖直觀,但標準庫單次掃描更高效、可移植。現代 C++ 專案建議直接使用 std::filesystem::path,若需相容舊標準,find_last_of 方案僅幾行程式碼即可完美替代 MFC 依賴。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved