You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下用C语言统计文件与子文件夹数量的代码错误排查求助

Fixing Your Windows File/Directory Counting Code

Hey there! Let's break down what's going wrong with your code and get it working on Windows properly.

First, Let's Fix the Obvious Code Mistakes

Looking at your error messages and code, there are two immediate issues that aren't even Windows-specific:

  1. Wrong Access to d_type: You're trying to access dir->d_type, but d_type is a member of the struct dirent pointer (dp), not the DIR pointer (dir). That's why you're getting the "'DIR' has no member named 'd_type'" error.
  2. Uninitialized Variable n: Your for loop uses i < n but n is never assigned a value. This will cause undefined behavior—we can just remove this loop entirely since it's not serving any purpose here.

Why the DT_REG/DT_DIR Errors Happen on Windows

The dirent.h header and constants like DT_REG/DT_DIR are part of POSIX standards, not Windows' native API. While some Windows compilers like MinGW provide a dirent.h implementation, it doesn't fully support d_type and those constants by default. Defining _BSD_SOURCE might help on MinGW, but it's not reliable across all Windows compilers (like MSVC, which doesn't include dirent.h at all).

Solution 1: Fix the Code for MinGW

If you're using MinGW, you can adjust your code to work with its dirent.h implementation:

#define _BSD_SOURCE  // Needed for d_type and DT_* constants in MinGW
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

void listFiles(const char *path);

int main() {
    char path[100];
    printf("Enter path to list files: ");
    scanf("%s", path);
    listFiles(path);
    return 0;
}

void listFiles(const char *path) {
    struct dirent *dp;
    DIR *dir = opendir(path);
    int fileCount = 0;
    int dirCount = 0;

    if (!dir) {
        printf("Failed to open directory!\n");
        return;
    }

    while ((dp = readdir(dir)) != NULL) {
        // Skip . and .. directories to avoid counting them
        if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) {
            continue;
        }
        if (dp->d_type == DT_REG) {  // Use dp instead of dir to access d_type
            fileCount++;
        } else if (dp->d_type == DT_DIR) {
            dirCount++;
        }
    }

    printf("%s: file count is: %d and dir count is: %d\n", path, fileCount, dirCount);
    closedir(dir);
}

Notes for this version:

  • The _BSD_SOURCE macro enables the POSIX-style d_type checks in MinGW's dirent.h.
  • We added checks to skip the . (current directory) and .. (parent directory) entries, which would otherwise inflate your directory count.

Solution 2: Windows Native API (Best for Full Compatibility)

If you want your code to work with all Windows compilers (like MSVC), use Windows' native file enumeration APIs (FindFirstFile and FindNextFile). This avoids relying on non-standard dirent.h entirely:

#include <stdio.h>
#include <windows.h>
#include <string.h>

void countFilesAndDirs(const char *path);

int main() {
    char path[100];
    printf("Enter path to list files: ");
    scanf("%s", path);
    countFilesAndDirs(path);
    return 0;
}

void countFilesAndDirs(const char *path) {
    WIN32_FIND_DATA findData;
    HANDLE hFind;
    int fileCount = 0;
    int dirCount = 0;
    char searchPath[MAX_PATH];

    // Build the search path: add "\*" to the end to find all entries in the directory
    snprintf(searchPath, MAX_PATH, "%s\\*", path);

    hFind = FindFirstFile(searchPath, &findData);
    if (hFind == INVALID_HANDLE_VALUE) {
        printf("Failed to open directory! Error code: %lu\n", GetLastError());
        return;
    }

    do {
        // Skip . and .. directories
        if (strcmp(findData.cFileName, ".") == 0 || strcmp(findData.cFileName, "..") == 0) {
            continue;
        }

        // Check if the entry is a directory using file attributes
        if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            dirCount++;
        } else {
            fileCount++;
        }
    } while (FindNextFile(hFind, &findData) != 0);

    // Clean up the file search handle
    FindClose(hFind);

    printf("%s: file count is: %d and dir count is: %d\n", path, fileCount, dirCount);
}

How this works:

  • FindFirstFile starts enumerating entries in the directory, and FindNextFile continues until there are no more entries left.
  • WIN32_FIND_DATA contains detailed information about each entry—we check dwFileAttributes for the FILE_ATTRIBUTE_DIRECTORY flag to distinguish directories from regular files.
  • This code uses Windows' native APIs, so it works seamlessly with all major Windows compilers and is the most reliable solution for the platform.

内容的提问来源于stack exchange,提问作者Eren sert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:07:47