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

如何在不使用dirent.h或Boost的情况下从零实现目录文件列表(课程项目)

从零实现目录文件名获取头文件(仅用指定可访问性函数)

Alright, let's tackle this head-on—your instructor's no-nonsense rule about ditching dirent.h/Boost means we have to get creative with the only tools we have: those accessibility-checking functions you mentioned. Here's a complete, compliant solution that builds everything from scratch.

Core Idea

Since we can't use system directory traversal APIs, we'll rely on brute-force enumeration + validation. On Windows (given the LPCSTR mention), all files have a compatible 8.3 short filename, so we can generate every possible valid short filename, then use your provided functions to check if it exists as a file (not a directory) in the target folder.

Header File (DirFileFetcher.h)

First, the header with clean declarations—we'll keep it minimal per best practices:

#ifndef DIR_FILE_FETCHER_H
#define DIR_FILE_FETCHER_H

#include <stddef.h>
#include <stdbool.h>

// Replace these with your actual function prototypes (match what you were given)
bool DoDirectoryExists(LPCSTR dirPath);
bool DoFileExists(LPCSTR filePath);

/**
 * Fetches all filenames in a specified directory
 * @param dirPath Target directory (MUST end with a backslash, e.g., "C:\\MyFiles\\")
 * @param fileNames Pre-allocated array of char* to store filenames
 * @param maxCount Maximum number of filenames the array can hold
 * @return Number of filenames found; returns 0 on invalid input or empty directory
 */
size_t GetDirectoryFiles(LPCSTR dirPath, char** fileNames, size_t maxCount);

#endif // DIR_FILE_FETCHER_H

Implementation (DirFileFetcher.c)

This is where the magic happens—we'll generate all possible 8.3 filenames and validate each one:

#include "DirFileFetcher.h"
#include <string.h>
#include <stdlib.h>

// Valid characters for 8.3 filenames (covers all standard Windows filename chars)
static const char* const VALID_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
static const size_t CHAR_COUNT = strlen(VALID_CHARS);

// Helper: Generates a string from an index (for brute-force combinations)
static void generate_string(char* out, size_t length, unsigned long long index) {
    memset(out, 0, length + 1);
    for (size_t i = 0; i < length; i++) {
        out[length - 1 - i] = VALID_CHARS[index % CHAR_COUNT];
        index /= CHAR_COUNT;
    }
}

size_t GetDirectoryFiles(LPCSTR dirPath, char** fileNames, size_t maxCount) {
    // Sanity checks first
    if (!dirPath || !fileNames || maxCount == 0 || !DoDirectoryExists(dirPath)) {
        return 0;
    }

    size_t found = 0;
    char full_path[260]; // MAX_PATH on Windows is 260, safe default
    size_t dir_len = strlen(dirPath);

    // Enumerate all possible 8.3 filenames: 1-8 chars for name, 0-3 for extension
    for (size_t name_len = 1; name_len <= 8 && found < maxCount; name_len++) {
        unsigned long long name_combinations = 1;
        for (size_t i = 0; i < name_len; i++) name_combinations *= CHAR_COUNT;

        for (unsigned long long name_idx = 0; name_idx < name_combinations && found < maxCount; name_idx++) {
            char name[9] = {0};
            generate_string(name, name_len, name_idx);

            // Check files with no extension first
            snprintf(full_path, sizeof(full_path), "%s%s", dirPath, name);
            if (DoFileExists(full_path) && !DoDirectoryExists(full_path)) {
                fileNames[found] = malloc(strlen(name) + 1);
                if (fileNames[found]) {
                    strcpy(fileNames[found], name);
                    found++;
                }
            }

            // Now check files with extensions (1-3 chars)
            for (size_t ext_len = 1; ext_len <= 3 && found < maxCount; ext_len++) {
                unsigned long long ext_combinations = 1;
                for (size_t i = 0; i < ext_len; i++) ext_combinations *= CHAR_COUNT;

                for (unsigned long long ext_idx = 0; ext_idx < ext_combinations && found < maxCount; ext_idx++) {
                    char ext[4] = {0};
                    generate_string(ext, ext_len, ext_idx);

                    snprintf(full_path, sizeof(full_path), "%s%s.%s", dirPath, name, ext);
                    if (DoFileExists(full_path) && !DoDirectoryExists(full_path)) {
                        size_t filename_len = strlen(name) + 1 + strlen(ext); // +1 for the dot
                        fileNames[found] = malloc(filename_len + 1);
                        if (fileNames[found]) {
                            sprintf(fileNames[found], "%s.%s", name, ext);
                            found++;
                        }
                    }
                }
            }
        }
    }

    return found;
}

Critical Notes for Your Project

  • Path Format: Make sure the input directory path ends with a backslash (\). If you forget this, the filename will be appended directly to the directory name (e.g., C:\Testfile.txt instead of C:\Test\file.txt), which will fail validation.
  • Memory Management: The caller is responsible for freeing each char* in the fileNames array after use—don't forget to add this to your usage example to show you understand memory safety.
  • Performance Tradeoff: Brute-force enumeration is slow, but it's the only way to do this without using directory-specific libraries. Be sure to mention this in your project documentation to demonstrate you recognize the limitation.
  • Long Filenames: This implementation relies on 8.3 short filenames, which Windows automatically generates for all files. So even if a file has a long name, its short name will be found here.

Usage Example

Show your instructor you know how to use the header properly:

#include <stdio.h>
#include "DirFileFetcher.h"

int main() {
    char* file_list[50]; // Allocate space for up to 50 filenames
    size_t file_count = GetDirectoryFiles("C:\\MyProject\\", file_list, 50);

    printf("Found %zu files:\n", file_count);
    for (size_t i = 0; i < file_count; i++) {
        printf("  - %s\n", file_list[i]);
        free(file_list[i]); // Clean up memory!
    }

    return 0;
}

内容的提问来源于stack exchange,提问作者Cain Wildtale

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 07:04:30