功能需求
- 輸入目標目錄 (如
E:\\) 與文件後綴 (如 txt)。
- 遞歸遍歷該目錄及所有子目錄。
- 刪除所有匹配後綴的文件 (直接刪除,不進回收站)。
- 統計並顯示刪除數量。
核心代碼 (關鍵函數)
#include
#include
#include
#include
int g_delCount = 0;
// 獲取文件後綴 (不含點)
char* getExt(const char *fname) {
static char ext[256];
const char *dot = strrchr(fname, '.');
if (!dot) { ext[0] = 0; return ext; }
strcpy(ext, dot + 1);
return ext;
}
// 遞歸遍歷並刪除
void findAndDelete(const char *dir, const char *targetExt) {
char searchPath[MAX_PATH];
snprintf(searchPath, MAX_PATH, "%s\\*", dir);
WIN32_FIND_DATA ffd;
HANDLE hFind = FindFirstFile(searchPath, &ffd);
if (hFind == INVALID_HANDLE_VALUE) return;
do {
if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0)
continue;
char fullPath[MAX_PATH];
snprintf(fullPath, MAX_PATH, "%s\\%s", dir, ffd.cFileName);
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// 子目錄:遞歸
findAndDelete(fullPath, targetExt);
} else {
// 文件:檢查後綴
if (_stricmp(getExt(ffd.cFileName), targetExt) == 0) {
printf("Deleting: %s\n", fullPath);
if (DeleteFile(fullPath)) g_delCount++;
else fprintf(stderr, "Failed: %s (err=%lu)\n", fullPath, GetLastError());
}
}
} while (FindNextFile(hFind, &ffd));
FindClose(hFind);
}
int main() {
char dir[MAX_PATH], ext[32];
printf("Enter directory (e.g. E:\\): "); fgets(dir, MAX_PATH, stdin);
dir[strcspn(dir, "\n")] = 0;
printf("Enter extension (e.g. txt): "); fgets(ext, 32, stdin);
ext[strcspn(ext, "\n")] = 0;
if (strlen(dir) == 0 || strlen(ext) == 0) return 1;
findAndDelete(dir, ext);
printf("\nTotal deleted: %d\n", g_delCount);
system("pause");
return 0;
}
關鍵 API 解析
| API | 用途 | 注意事項 |
FindFirstFile / FindNextFile | 目錄遍歷 | 需 windows.h,返回 WIN32_FIND_DATA 含屬性、文件名 |
FILE_ATTRIBUTE_DIRECTORY | 判斷是否目錄 | 位掩碼檢查 |
DeleteFile | 刪除文件 | 永久刪除,不進回收站;需權限 |
_stricmp | 大小寫無關比較 | Windows 專用,跨平台用 strcasecmp |
snprintf | 安全格式化路徑 | 防止緩衝區溢出 |
編譯指南
# MinGW-GCC (推薦)
gcc del_ext.c -o del_ext.exe -Wall -Wextra -municode
# MSVC (Visual Studio Developer Command Prompt)
cl del_ext.c /W4 /EHsc /D_UNICODE /DUNICODE
Unicode 支援:文件名可能含中文。定義 _UNICODE 使用 TCHAR/FindFirstFileW,或確保源文件 UTF-8 編譯並用 FindFirstFileA (ANSI 版),現代 Windows 兼容良好。
安全警示與改進
⚠️ 危險操作: 直接調用 DeleteFile 無法撤銷!生產環境必須:
- 移至回收站:
SHFileOperation with FO_DELETE | FOF_ALLOWUNDO。
- 二次確認:列出待刪文件,用戶確認後再執行。
- 乾跑模式:
--dry-run 參數僅列出不刪除。
- 日誌記錄:記錄刪除時間、路徑、文件大小、哈希,便恢復/審計。
- 權限檢查:
GetFileAttributes 檢查 FILE_ATTRIBUTE_READONLY 等。
跨平台版本思路 (C++17)
#include
#include
#include
namespace fs = std::filesystem;
int main() {
fs::path dir; string ext;
cout << "Dir: "; cin >> dir;
cout << "Ext: "; cin >> ext;
int cnt = 0;
for (auto& e : fs::recursive_directory_iterator(dir)) {
if (e.is_regular_file() && e.path().extension() == "." + ext) {
cout << "Deleting: " << e.path() << "\n";
fs::remove(e.path()); // 或移至回收站
cnt++;
}
}
cout << "Total: " << cnt << "\n";
}
標準庫 std::filesystem (C++17) 跨平台、異常安全、編碼處理更好,強烈推薦新項目使用。
- 上一篇文章: 數據結構課程設計:平衡二叉樹(AVL)完整實現與核心操作詳解
- 下一篇文章: GCC 宏定義參數技巧、CodeBlocks 配置陷阱與 Glib 字符串化最佳實踐
Copyright ©
程式碼之家 All Rights Reserved