【问题标题】:Problem reading directories in C在 C 中读取目录时出现问题
【发布时间】:2011-11-20 15:58:37
【问题描述】:

我正在编写一个简单的 C 程序,它接收一个目录作为参数,并显示该目录中的文件及其子目录。我为此编写了一个“递归”函数。但由于未知原因,我的程序在 stat 函数处失败。这是我的程序:

    #define _POSIX_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>


void display_directory(char* path){

  DIR* directory = opendir(path);
  if( directory == NULL){
    printf("opendir failure for %s\n", path);
    exit(1);
  }


 struct dirent* dirent;
 struct stat stat_info;

 while((dirent = readdir(directory)) != NULL){
   printf("[%s]\n", dirent->d_name);
   if(stat(dirent -> d_name, &stat_info) == -1){
     printf("readdir error for %s\n", dirent->d_name);
     exit(1);
   }
   if(S_ISREG(stat_info.st_mode)){
       printf("File: %s \n", dirent -> d_name); 
   }
   if(S_ISDIR(stat_info.st_mode)){
     if(strncmp(dirent->d_name, "..",2)){
       printf("Directory : %s\n", dirent->d_name);
       display_directory(dirent->d_name);
     }  
    }

 }

 closedir(directory);
}

int main(int argc, char* argv[]){

char* path;

if(argc > 1){
 path = argv[1];
} else {
 path = ".";
}

display_directory(path);

 return EXIT_SUCCESS;
}

例如,如果在我的目录A中,我有a1、a2、a3和..,它首先读取..目录,当它读取目录a1时,stat函数失败。

谁能告诉我我的代码有什么不正确的地方。

[编辑] 我包含了&lt;errno.h&gt;,正如你们中的许多人所建议的那样,运行程序后,我遇到了错误Too many open files

    #define _POSIX_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>


void display_directory(char* path){

  DIR* directory = opendir(path);
  if( directory == NULL){
    printf("opendir failure for %s --> %s\n", path, strerror(errno));
    exit(1);
  }


 struct dirent* dirent;
 struct stat stat_info;

 while((dirent = readdir(directory)) != NULL){
   printf("[%s]\n", dirent->d_name);
   if(stat(dirent->d_name, &stat_info)){
     printf("readdir error for %s ---> %s\n", dirent->d_name, strerror(errno));
     continue;
   }
   if(S_ISREG(stat_info.st_mode)){
       printf("Fichier : %s \n", dirent->d_name); 
   }
   if(S_ISDIR(stat_info.st_mode)){
     if(strncmp(dirent->d_name, "..",2)){
       printf("Directory : %s\n", dirent->d_name);
       display_directory(dirent->d_name);
     }  
    }

 }

 closedir(directory);
}

int main(int argc, char* argv[]){

char* path;

if (argc > 2) { 
 fprintf(stderr, "Usage: %s [directory]\n", argv[0]); 
 exit(1); 
}

path = argv[1];


display_directory(path);

 return EXIT_SUCCESS;
}

程序的输出:

[..]
[mykill.c]
readdir error for mykill.c ---> No such file or directory
[.]
Directory : .
[..]
[.]
Directory : .
[..]
[.]
Directory : .
[..]

...
...
Directory : .
opendir failure for . --> Too many open files

mykill.c 是目录中作为参数传递的文件。

【问题讨论】:

  • 你看errno了吗?
  • 不要在主要运算符a.ba-&gt;b 周围使用空格。对于有经验的程序员来说,这看起来很奇怪。
  • 一个更好的主函数设计将处理命令行上的所有参数:if (argc == 1) display_directory("."); else { for (int i = 1; i &lt; argc; i++) display_directory(argv[i]); }
  • @OliCharlesworth Nop 我没看 errno。
  • @JonathanLeffler 是的,但我的程序只接受一个参数。

标签: c directory stat


【解决方案1】:

我很清楚出了什么问题,但我想先告诉你如何自己调试它。更改此代码...

if(stat(dirent -> d_name, &stat_info) == -1){
  printf("readdir error for %s\n", dirent->d_name);
  exit(1);
}

...改为阅读...

if (stat(dirent->d_name, &stat_info)) {
    printf("%s: %s\n", dirent->d_name, strerror(errno));
    continue;
}

您需要添加到包含列表中

#include <errno.h>

再次运行程序。如果您从输出中看不到问题所在,则将 COMPLETE, UNEDITED 输出编辑到您的问题中,我们将从那里开始。

【讨论】:

    【解决方案2】:
    if(S_ISDIR(stat_info.st_mode)){
     if( !strcmp(dirent->d_name, ".")) continue;
     if( !strcmp(dirent->d_name, "..")) continue;
    
     printf("Directory : %s\n", dirent->d_name);
     display_directory(dirent->d_name);
    }
    

    【讨论】:

      【解决方案3】:

      您只使用文件名(没有完整路径)进行统计,在调用 stat 之前添加文件名的完整路径或更改工作目录。

      【讨论】:

        【解决方案4】:

        使用nftw()

        【讨论】:

          猜你喜欢
          • 2011-08-03
          • 2015-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-28
          • 2021-03-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多