【问题标题】:List folders, sub folders and files in a given path in C (windows)列出 C 中给定路径中的文件夹、子文件夹和文件(Windows)
【发布时间】:2016-10-03 22:29:06
【问题描述】:

有没有办法列出给定路径中的所有文件夹、子文件夹和文件?例如:(c:\myfolder),并打印其中包含的每个文件和文件夹的完整路径?

c:\myfolder\folder1\
c:\myfolder\folder2\
c:\myfolder\folder2\f1
c:\myfolder\folder2\f2\g1
c:\myfolder\test.txt
c:\myfolder\t.txt

我找到了这个例子,但只为 linux 设计:

int is_directory_we_want_to_list(const char *parent, char *name) {
    struct stat st_buf;
    if (!strcmp(".", name) || !strcmp("..", name))
        return 0;

    char *path = alloca(strlen(name) + strlen(parent) + 2);
    sprintf(path, "%s/%s", parent, name);
    stat(path, &st_buf);
    return S_ISDIR(st_buf.st_mode);
}

int list(const char *name) {
    DIR *dir = opendir(name);
    struct dirent *ent;

    while (ent = readdir(dir)) {
        char *entry_name = ent->d_name;
        printf("%s\n", entry_name);

        if (is_directory_we_want_to_list(name, entry_name)) {
            // You can consider using alloca instead.
            char *next = malloc(strlen(name) + strlen(entry_name) + 2);
            sprintf(next, "%s/%s", name, entry_name);
            list(next);
            free(next);
        }
    }

    closedir(dir);
}

来源: How to recursively list directories in C on LINUX

【问题讨论】:

  • 你的编译器是什么?
  • @BLUEPIXY 我正在使用Visual Studio 2010
  • 尝试使用_popentree /F 命令或dir /S /B /OG 命令。
  • @BLUEPIXY 我需要一个代码,因为我需要在每个文件中进行操作。

标签: c windows


【解决方案1】:

正如@purplepsycho 所建议的,最简单的方法是使用 FindFirstFile、FindNextFile 和 FileClose。

但无论如何与 Unix 版本有一些区别:您必须搜索像 folder\* 这样的名称,而不是浏览目录,FindFirstFile 给出名字,而其他名称则使用 FindNextFile

这是一个完整的代码示例:

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

#ifdef UNICODE
#define fmt "%S"
#else
#define fmt "%s"
#endif

void process_file(LPCTSTR filename) {
    // TODO: implement actual file processing
    printf(fmt, filename);
    fputs("\n", stdout);
}

void process_folder(LPCTSTR foldername) {
    WIN32_FIND_DATA findFileData;
    HANDLE handle;
    LPTSTR newfolder = malloc(sizeof(TCHAR) *(_tcslen(foldername) + 3));  // add some room for the additional \*
    _tcscpy(newfolder, foldername);
    _tcscat(newfolder, _T("\\*"));
    handle = FindFirstFile(newfolder, &findFileData);
    if (handle != INVALID_HANDLE_VALUE) {
        while(1) {
            // skip . and .. to avoid infinite recursion
            if ((_tccmp(findFileData.cFileName, _T(".")) != 0) && (_tccmp(findFileData.cFileName, _T("..")) != 0)) {
                // compute name as folder\filename
                LPTSTR newname = malloc(sizeof(TCHAR) * (_tcslen(foldername) + _tcslen(findFileData.cFileName) + 2));
                _tcscpy(newname, foldername);
                _tcscat(newname, _T("\\"));
                _tcscat(newname, findFileData.cFileName);
                if ((findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
                    process_folder(newname); // recurse if is is a directory
                }
                else {
                    process_file(newname);  // process other files
                }
                free(newname);  // consistenly free any malloc
            }
            if (FindNextFile(handle, &findFileData) == FALSE) break; // exit the loop when folder is exhausted
        }
        FindClose(handle);
    }
    free(newfolder); 
}

int _tmain(int argc, TCHAR *argv[]) {
    if (argc != 2) {
        fputs("Usage: ", stderr);
        fprintf(stderr, fmt, argv[0]);
        fputs(" top_folder\n", stderr);
        return 1;
    }
    process_folder(argv[1]);
    return 0;
}

上面的代码仍然缺少一些错误条件处理,但它是在 Windows 上递归使用 Find{First|Next}File 的一个示例。

【讨论】:

  • 这段代码是用 C++ 编写的,我想要一个 C 示例作为 montionned :) 无论如何谢谢你的贡献。
  • @CoderAsker:哎呀,我的错 :-( 希望很容易将其转换为 C...
  • 在您的代码中检测到许多错误,并且转换效果不佳...无法解决问题,抱歉 :)
  • @CoderAsker:在旧的 VC2008 下,无论是 unicode 还是 ansi 模式,它都可以编译和运行而没有错误(由于tcscpytcscat 函数,只有警告)。你发现了什么错误?
  • 我收到如下错误:error LNK2001: unresolved external symbol __tccmp
【解决方案2】:

_popendir /S /B /OG 一起使用。
(可以减少代码)

代码示例。
(文件夹的显示位置可能与预期不同。DIY :-)

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

int main(int argc, char *argv[]){
    if(argc != 2){
        fprintf(stderr, "Usage : %s path\n", argv[0]);
        return -1;
    } else {
        char buff[1024];//or MAX_PATH + α
        FILE *fp;

        sprintf(buff, "dir %s /S /B /OG", argv[1]);
        if(NULL == (fp = _popen(buff, "r"))){
            perror("can't open pipe");
            return -2;
        }
        while(fgets(buff, sizeof buff, fp)){
            char *p = strchr(buff, '\n');
            *p = 0;
            if(FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(buff)){
                *p = '\\';
                p[1] = '\0';
            }
            puts(buff);
        }
        _pclose(fp);
    }
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-11
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2013-05-01
    相关资源
    最近更新 更多