實務中常遇到 file.tar.gz、setup.exe.config 等多層副檔名,需提取最內層(最右側)副檔名進行類型判斷。本文提供基於 MFC CString 的遞迴解析方案,並給出標準 C++ 替代實作。
#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.exe | exe | exe |
| 11.exe.wmv | exe.wmv → wmv | wmv |
| 111.exe.wmv.txt | exe.wmv.txt → wmv.txt → txt | txt |
| README | README | 未知(README) |
| .gitignore | gitignore | 未知(gitignore) |
#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. | 回傳 "" | 回傳 "" |
std::filesystem::path (C++17) 提供 .extension() 直接取得含點號的副檔名unordered_set<string> 存儲允許的副檔名,O(1) 查找file.exe.jpg 可能偽裝圖片,伺服器端應檢查 Magic Number 而非單信副檔名遞迴解析雖直觀,但標準庫單次掃描更高效、可移植。現代 C++ 專案建議直接使用 std::filesystem::path,若需相容舊標準,find_last_of 方案僅幾行程式碼即可完美替代 MFC 依賴。