【问题标题】:How to find all the file names in a specific directory without using "dirent.h" (visual studio 2017 windows) in C如何在 C 中不使用“dirent.h”(visual studio 2017 windows)在特定目录中查找所有文件名
【发布时间】:2019-05-24 12:36:15
【问题描述】:

我有一个期中项目,要制作一个防病毒软件,主要参数是一个目录和一个路径: 该路径指向包含病毒签名的文件。防病毒软件的目标是扫描给定目录中的所有文件以查找病毒签名。 我已经完成了整个项目,除了在特定给定目录中找到所有文件的部分。由于这个项目是由一个没有任何外部库并在未知操作系统上运行的自动反馈系统检查的(即使我的老师也不知道,这是课程的系统),它有成为一个跨平台的解决方案,不依赖任何库,只依赖于 stdio.h、stdlib.h、string.h 和 windows.h

几乎每个教程和这样做的示例都使用 HANDLE(我们还没有学过,也不应该使用)或使用 . 问题是要找到一种不需要直接库的方法。

我需要一些函数来获取目录中的所有文件

类似这样的:

char** fileNames = somefunc(char* dir)

【问题讨论】:

  • 如果没有某种库,那无法完成。文件遍历不是标准C,需要调用OS。
  • 这对你的导师来说可能是一个更好的问题:对你施加这些(假定的)限制的人。
  • 没有“跨平台解决方案”可以做到这一点。为此,您需要使用操作系统本机功能。也许是时候让你的老师澄清一下了?
  • 对于Windows,原生解决方案是使用FindFirstFileFindNextFile(如果包含<windows.h>,则会声明)。
  • @LiorLevin 如果你的目标是“打破你的头脑”,告诉他你已经做到了,你知道没有答案。这就像要求某人在不教他们进位的情况下将 28 + 17 相加——解决方案是“你不能”;你必须学习携带。 (另外,你的导师在骗你。如果你可以使用<windows.h>,他知道操作系统是Windows。)

标签: c file


【解决方案1】:

仅使用标准库无法做到这一点;标准 C 不了解目录。不过,每个操作系统都有执行此操作的方法,因此您需要为您的检查器找到操作系统系列(Windows、Linux 等)并查找如何为该操作系统执行此操作。

操作系统中内置的库必须可用,因为它们是系统自带的。没有它们,您根本无法运行任何程序。 (这在技术上是不正确的,但它足以涵盖所有有趣的案例。)

编辑:如果您的检查器在 Windows 下运行(从您的 cmets 判断),您将需要使用 FindFirstFileFindNextFile。不过,它们确实依赖于句柄(就像几乎所有的 Windows API 一样),所以你必须研究一下。 (句柄只是一个对 Windows 内核具有特殊含义的不透明指针。您可以将其视为 void *。不要太拘泥于数据类型。)

编辑 2:如果您正在寻找可以帮助您入门的东西:

char ** list_directory (const char * directory) {
  char * search_path = malloc(strlen(directory) + 3);
  strcpy(search_path, directory);
  strcat(search_path, "\\*");
  WIN32_FIND_DATA fd;
  SetLastError(0);
  HANDLE hsrch = FindFirstFile(search_path, &fd);
  free(search_path);
  if (hsrch == INVALID_HANDLE_VALUE) {
    if (GetLastError() != ERROR_FILE_NOT_FOUND) return NULL;
    SetLastError(0);
    return calloc(1, sizeof(char *)); // no files
  }
  char ** result = malloc(sizeof(char *));
  unsigned count = 0;
  while (!GetLastError()) {
    result[count] = malloc(strlen(fd.cFileName) + 1);
    strcpy(result[count ++], fd.cFileName);
    FindNextFile(hsrch, &fd);
    result = realloc(result, (count + 1) * sizeof(char *));
  }
  if (GetLastError() == ERROR_NO_MORE_FILES)
    SetLastError(0);
  FindClose(hsrch);
  result[count] = NULL;
  return result;
}

【讨论】:

    【解决方案2】:

    dirent.h 标头是遍历目录的 POSIX 实现,这意味着它只能在类 UNIX 系统上运行。对于 Windows,您应该使用 here 指定的 _findfirst_findnext 函数。与FindFirstFileFindNextFile 不同,它们不使用HANDLE

    例如:

    intptr_t ffhandle;
    struct _finddata_t ffinfo;
    
    if ((ffhandle = _findfirst("c:\\path\\to\\dir\\*.*", &ffinfo)) == -1) {
        perror("findfirst failed");
        exit(1);
    }
    do {
        printf("found file %s\n", ffinfo.name);
    } while (_findnext(ffhandle, &ffinfo) == 0);
    _findclose(ffhandle);
    

    【讨论】:

    • 不过,这只是一个转换为 intptr_t 的句柄。
    • @aaaaaa123456789 没有演员表。这些函数被声明为返回intptr_t
    • 演员在函数的实现中。 HANDLE 是一个不透明的指针类型。
    • @aaaaaa123456789,_findfirst 返回的数字与HANDLE 的关系既未指定也不相关。如果禁止 OP 依赖 HANDLE 类型,那么这种方法可以实现。
    猜你喜欢
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 2019-06-06
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 2012-09-16
    相关资源
    最近更新 更多