【问题标题】:How to print the desired file from a directory?如何从目录打印所需的文件?
【发布时间】:2021-03-01 09:43:36
【问题描述】:

在这段代码中,我打印了基本目录中的所有文件。但我想更具体一点,只打印我想要的文件。我该怎么做?

int specificSelection(char *basePath, char *specificFile){
    struct dirent *dp;
    DIR *dir;
    int count=0;

    if ( NULL != ( dir = opendir ( basePath))) {
        while ( NULL != ( dp = readdir(dir))) {
            if (strcmp ( dp->d_name, ".") != 0 && strcmp ( dp->d_name, "..") != 0) {
                strcpy(specificFile, dp->d_name);
                if ( dp->d_type == DT_REG) {
                    printf("%s\n", specificFile);
                }
            }
        }
        closedir(dir);
    }
    else {
        perror (basePath);
    }
    return 0;
}

int main(){
  char pathname1[200] = "/home/runner/TestC1";
  char path[100] = "filename.txt";

  listdir(pathname1, path);

  return 0;
}

【问题讨论】:

  • 你能使用与“.”相同的条件吗?和“..”?
  • 您可以检查它是否是您需要的文件,而不是检查它是否不是... - 顺便说一下,您当前的代码将崩溃或至少损坏内存通过任何名称比您传入的名称长的文件,您不能那样使用strcpy(事实上,您不应该使用strcpy永远,正因为如此它不能限制长度)
  • 目前,您正在将文件名复制到specificFile 指向的内存中。听起来specificFile 已经包含一个文件名(可能应该是const)。在这种情况下,您需要使用strcmp 将文件与specificFile 进行比较,直到找到所需的文件。
  • 请说明您如何称呼specificSelectionstrcpy(specificFile, dp->d_name) 的目的是什么?为什么不简单地printf("%s\n", dp->d_name)specificFile 参数到底是什么?你的声望超过 50 点,所以我想你知道 minimal reproducible example 是什么
  • @user3121023 这将是一种非常复杂的方法来检查文件是否存在于目录中并在存在时打印其名称......

标签: c


【解决方案1】:

您的代码基本上只是检查文件是否存在:

您可以使用access 函数以更简单的方式执行此操作:

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

int specificSelection(char *basePath, char *specificFile){
  char filename[1000];
  strcpy(filename, basePath);
  strcat(filename, specificFile); // filename contains now the absolute path to
                                  // the file, e.g. "/home/runner/TestC1/filename.txt"

  if (access(filename, F_OK) == 0)  // check if file exists
  {
    printf("%s\n", filename);       // print filename if it exists
  }

  return 0;
}
...

免责声明:

  • 这是未经测试的代码,可能无法正常工作
  • 没有错误检查
  • 如果文件路径的总长度超过 999,代码将不起作用。

您可以使用stat 函数代替access 函数,这样可以进行更多控制。

【讨论】:

    【解决方案2】:

    您也可以将fnmatchscandir 一起使用:

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <dirent.h>
    #include <fnmatch.h>
    
    static char *filename;
    
    static int selection(const struct dirent *entry)
    {
        if (fnmatch(filename, entry->d_name, FNM_PATHNAME | FNM_PERIOD) == 0)   
            return 1;
    
        return 0;
    }
    
    int main()
    {
        char pathname[200] = "/home/runner/TestC1";
        char path[100] = "filename.txt";
    
        filename = path;
    
        struct dirent **list;
    
        int nb_entries = scandir(pathname, &list, selection, NULL);
    
        if (nb_entries >= 0) {
    
            if (nb_entries == 1) { /* found */
    
                printf("%s\n", list[0]->d_name);
                free(list[0]);
            }    
            free(list);
        }
        return 0;
    }
    

    请注意,这只是一个示例。 如果需要,您还可以轻松扩展此代码以使用正则表达式。

    【讨论】:

      【解决方案3】:

      在本节中:

      if (strcmp ( dp->d_name, ".") != 0 && strcmp ( dp->d_name, "..") != 0) {
                  strcpy(specificFile, dp->d_name);
                  if ( dp->d_type == DT_REG) {
                      printf("%s\n", specificFile);
                  }
              }
      

      该逻辑将输出任何找到的不 == ... 的字符串,并且它的 d_type == DT_REG。这似乎与声明的需求不符:

      “但我想更具体一些,只打印我想要的文件”

      考虑使用strstr()进行以下修改

      if (strstr( dp->d_name, specificFile) ) {
         if( dp->d_type == DT_REG) {
               printf("%s\n", specificFile);//if only filename is desired, 
               printf("%s\n", dp->d_name);//or if entire line is desired, 
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-23
        • 1970-01-01
        • 2017-03-15
        • 1970-01-01
        • 1970-01-01
        • 2016-05-03
        • 2017-04-03
        • 2017-10-17
        相关资源
        最近更新 更多