Windows下用C语言统计文件与子文件夹数量的代码错误排查求助
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:
- Wrong Access to
d_type: You're trying to accessdir->d_type, butd_typeis a member of thestruct direntpointer (dp), not theDIRpointer (dir). That's why you're getting the "'DIR' has no member named 'd_type'" error. - Uninitialized Variable
n: Yourforloop usesi < nbutnis 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_SOURCEmacro enables the POSIX-styled_typechecks in MinGW'sdirent.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:
FindFirstFilestarts enumerating entries in the directory, andFindNextFilecontinues until there are no more entries left.WIN32_FIND_DATAcontains detailed information about each entry—we checkdwFileAttributesfor theFILE_ATTRIBUTE_DIRECTORYflag 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

