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

C語言實戰:遞歸遍歷目錄刪除指定後綴文件 (Windows API 版,含完整源碼與編譯指南)

     編輯:關於C語言

功能需求

  • 輸入目標目錄 (如 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 解析

編譯指南


# 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 無法撤銷!生產環境必須:

  1. 移至回收站:SHFileOperation with FO_DELETE | FOF_ALLOWUNDO。
  2. 二次確認:列出待刪文件,用戶確認後再執行。
  3. 乾跑模式:--dry-run 參數僅列出不刪除。
  4. 日誌記錄:記錄刪除時間、路徑、文件大小、哈希,便恢復/審計。
  5. 權限檢查: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) 跨平台、異常安全、編碼處理更好,強烈推薦新項目使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
API用途注意事項
FindFirstFile / FindNextFile目錄遍歷需 windows.h,返回 WIN32_FIND_DATA 含屬性、文件名
FILE_ATTRIBUTE_DIRECTORY判斷是否目錄位掩碼檢查
DeleteFile刪除文件永久刪除,不進回收站;需權限
_stricmp大小寫無關比較Windows 專用,跨平台用 strcasecmp
snprintf安全格式化路徑防止緩衝區溢出