【问题标题】:How do I read files from an string array of file names?如何从文件名字符串数组中读取文件?
【发布时间】:2019-11-27 23:21:18
【问题描述】:

所以我编写了一个程序来打开一个目录,获取里面的所有文件,然后读取每个文件的内容。目前我成功地获得了字符串数组中的所有文件名。 print files[] 循环显示所有文件名,但检查频率的循环没有正确读取文件。我如何成功读取文件名数组,然后扫描它们的每个内容?

//Open Directory
        DIR *dr = opendir(path);
        struct dirent *de;
        if(dr == NULL){
                printf("Could not open directory");
                return 0 ;
        }
        const char* files[100];
        int buffer=0;
        //Read Directory Files
        while((de = readdir(dr)) != NULL){
                files[buffer] = de->d_name;
                buffer++;
        }
        for(int x = 0; x <= buffer; x++){
                printf("%s" , files[x]);
        }
        closedir(dr);
        //Check Frequency
        for(int i = 0; i <= buffer; i++){
                int ch;
                FILE *fp;
                fp = fopen(files[i], "r");
                if(fp == NULL)
                        continue;
                ch = fgetc(fp);
                while(ch != EOF){
                        ch = tolower(ch);
                        if(ch>=97 && ch<= 122){
                                alphabetfreq[ch-97]++;
                        }
                        ch = fgetc(fp);
                }
        fclose(fp);

【问题讨论】:

  • 问题似乎出在“检查频率”循环中
  • 您不能简单地将指针从de-&gt;d_name 分配给您的数组。 de-&gt;d_name 是一个内部变量,很可能被readdir 重用。您应该为每个名称分配并存储名称而不是指向de-&gt;d_name
  • alphabetfreq[] 定义和许多其他缺失。评论minimal reproducible example
  • 发布的代码缺少对子目录的检查。发布的代码缺少对 ... 文件名的检查。发布的代码缺少对符号链接的检查

标签: c arrays file unix directory


【解决方案1】:

程序有很多问题。但它不读取文件的主要原因是您只是将文件名传递给 fopen(),因此它正在当前目录中查找它们并返回空值。此外,您没有仔细处理空结果。并且循环中的条件应该是 x

#include<stdio.h>
#include<dirent.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

int main()
{
  int alphabetfreq[100], i;
  for(i = 0; i < 100; i++){
    alphabetfreq[i] = 0;
  }
  char path[] =  "/home/path_to_directory/";
  DIR *dr = opendir(path);
       struct dirent *de;
       if(dr == NULL){
               printf("Could not open directory");
               return 0 ;
       }
       const char* files[100];
       int buffer=0;
       //Read Directory Files
       while((de = readdir(dr)) != NULL){
               files[buffer] = de->d_name;
               buffer++;
       }
       for(int x = 0; x < buffer; x++){
               printf("%s" , files[x]);
       }
       closedir(dr);
       printf("\n");
       //Check Frequency
       for(int i = 0; i < buffer; i++){
               int ch;
               FILE *fp;
               char * file = malloc(strlen(path) + strlen(files[i]) + 1);
               strcpy(file, path);
               strcat(file, files[i]);
               fp = fopen(file, "r");
               if(fp == NULL)
              {
                printf("no file %s\n", file);
                continue;
              }
               ch = fgetc(fp);
               while(ch != EOF){
                       ch = tolower(ch);
                       if(ch>=97 && ch<= 122){
                               alphabetfreq[ch-97]++;
                       }
                       ch = fgetc(fp);
               }

       fclose(fp);
     }

     for(i = 0; i < 26; i++)
     {
       printf("%c %d\n", i+97, alphabetfreq[i]);
     }
}

这对我有用。

【讨论】:

  • files[buffer] = de-&gt;d_name; 遇到与原始问题下的 cmets 中提到的相同问题。
  • 另外,文件名的数量是硬编码的;可能有超过 100 个文件。为什么不为每个文件名分配空间,包括读取目录的循环中的路径?无论如何,您的来源不会释放内存。
  • 我认为从de-&gt;d_name 复制指针值是可以的,因为我们只需要读取它(至少在这种情况下)。更好的选择是创建一个de 类型的指针数组并将返回值存储在那里。
猜你喜欢
  • 2019-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-08
  • 2019-05-23
相关资源
最近更新 更多