使用C语言打开目录

20

我通过命令行输入来接受路径。

当我执行以下操作时

dir=opendir(args[1]);

它没有进入循环...即 dir==null...

我如何将命令行输入传递给dir指针?

void main(int c,char **args)
{
    DIR *dir;
    struct dirent *dent;
    char buffer[50];
    strcpy(buffer, args[1]);
    dir = opendir(buffer);   //this part
    if(dir!=NULL)
    {
        while((dent=readdir(dir))!=NULL)
            printf(dent->d_name);
    }
    close(dir);
}

./a.out  /root/TEST is used to run the program..
./a.out --> to execute the program
/root/TEST --> input by the user i.e valid path

2
请提供您代码的相关部分。对我来说,您的问题不够清晰。opendir返回一个DIR *。它在两种情况下返回NULL:无法访问目录或无法分配内存以保存结果。 - jweyrich
1
@Vinod K - 请回顾您以前的问题。找到最好回答该问题的答案(如果有的话),然后点击灰色轮廓的“打勾”符号(它应该变成绿色)。 - detly
1
我要冒昧建议一下,/root/TEST 不是一个目录或者你没有权限搜索该目录。尝试使用 /tmp. 作为代码中的目录。 - paxdiablo
@Vinod K:点击所希望接受的答案左侧的勾号,它就在投票赞成/反对按钮下方。 - Thanatos
1
啊,是的,臭名昭著的Heisenbug :-) - paxdiablo
显示剩余10条评论
4个回答

53

你应该真正地发布你的代码(a),但是这里有一些提示。从这里开始:

    #include <stdio.h>
    #include <dirent.h>

    int main (int argc, char *argv[]) {
        struct dirent *pDirent;
        DIR *pDir;

        // Ensure correct argument count.

        if (argc != 2) {
            printf ("Usage: testprog <dirname>\n");
            return 1;
        }

        // Ensure we can open directory.

        pDir = opendir (argv[1]);
        if (pDir == NULL) {
            printf ("Cannot open directory '%s'\n", argv[1]);
            return 1;
        }

        // Process each entry.

        while ((pDirent = readdir(pDir)) != NULL) {
            printf ("[%s]\n", pDirent->d_name);
        }

        // Close directory and exit.

        closedir (pDir);
        return 0;
    }
你需要检查你的情况,确定args[1]已设置并且指向实际目录。一个样例运行,其中tmp是当前目录的子目录,但你可以使用任何有效的目录,它会给出: testprog tmp
[.]
[..]
[file1.txt]
[file1_file1.txt]
[file2.avi]
[file2_file2.avi]
[file3.b.txt]
[file3_file3.b.txt]

注意,你需要传递一个目录而不是一个文件。 当我执行以下命令时:

testprog tmp/file1.txt

我得到:

Cannot open directory 'tmp/file1.txt'

这是因为它是一个文件而不是目录(虽然,如果你足够狡猾,可以尝试使用diropen(dirname(argv[1])),如果初始的diropen失败)。


(a)现在这个问题已经解决了,但由于此答案已被接受,我假设这可能与您传递的任何内容有关。


我是说...而不是 pDir=opendir("Hardcoding the path") 我们能不能像这样写pDir=opendir(args[1]) 用户输入的内容? - Vinod K
1
如何避免遍历到 [.] 和 [..]? - Jason John
@jaytj95,你这里并没有遍历层次结构,只是在一个级别上进行操作。但逻辑类似。在循环中,只需使用strcmppDirent->d_name与要忽略的项进行比较,并仅对其他项执行printf/遍历操作。 - paxdiablo

3

对于代码片段的一些反馈,尽管大部分应该可以正常工作...

void main(int c,char **args)
  • int main - 标准规定 main 函数返回一个 int 类型的值。
  • cargs 通常分别命名为 argcargv,但您可以给它们任何名称。

...

{
DIR *dir;
struct dirent *dent;
char buffer[50];
strcpy(buffer,args[1]);
  • 您在这里有一个缓冲区溢出问题:如果args [1]超过50个字节,buffer将无法容纳它,您将写入不应该写入的内存。我看不到在此处复制缓冲区的理由,因此您可以通过不使用strcpy来避开这些问题...

...

dir=opendir(buffer);   //this part

如果返回的是NULL,可能有以下几个原因:

  • 目录不存在。(您是否正确输入了它?它是否有空格,您输入了./your_program my directory,这将失败,因为它尝试执行opendir("my")
  • 您缺少访问该目录的权限。
  • 内存不足。(这很不可能。)

2
传递给C程序可执行文件的参数实际上是一个字符串数组(或字符指针),因此在程序访问这些参数之前,内存已经为这些输入参数分配好了,所以不需要分配缓冲区,这样可以避免在程序中编写错误处理代码(减少段错误的机会 :))。

0

以下是一种使用 C 实现 ls 命令的简单方法。例如,要运行,请使用 ./xls /tmp 命令。

    #include<stdio.h>
    #include <dirent.h>
    void main(int argc,char *argv[])
    {
   DIR *dir;
   struct dirent *dent;
   dir = opendir(argv[1]);   

   if(dir!=NULL)
      {
   while((dent=readdir(dir))!=NULL)
                    {
        if((strcmp(dent->d_name,".")==0 || strcmp(dent->d_name,"..")==0 || (*dent->d_name) == '.' ))
            {
            }
       else
              {
        printf(dent->d_name);
        printf("\n");
              }
                    }
       }
       close(dir);
     }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接