对象中的C遍历目录和打印条目

时间:2017-02-16 02:10:27

标签: c directory

假设我有以下代码抽象:

  DIR *d;
  struct dirent *sd; 
  d = opendir("SOME DIRECTORY");
  // handle errors 
  sd = readdir(d);
  while(sd != NULL){
    printf("(%s, %s)\n", sd->d_name, sd->the_next_d_name);
    sd = readdir(d);
  }
  closedir(dir);

我对c有点新,并且会使用man页面详细介绍。我只是想了解如何在循环体中访问目录的两个条目。该代码使用一些伪名称来实现这个想法。此外,如果有奇数个条目,我希望最后一对有一个条目与NULL配对

无论如何,谢谢。

1 个答案:

答案 0 :(得分:0)

主要问题是readdir()函数在第二次调用时不保留以前返回的值:

  

应用程序不应修改readdir()的返回值指向的结构,也不应修改结构中指针指向的任何存储区域。返回的指针和结构中的指针可能无效,或者结构或存储区域可能会被同一目录流上的readdir()的后续调用覆盖。它们不会受到对不同目录流的readdir()的调用的影响。

因此,您必须为每对条目中的第一个复制一个名称。据推测,你有strdup()可用,所以这是最小的痛苦。 (如果你没有strdup(),很容易编写自己的版本--7行,包括只有大括号的行。)

#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "stderr.h"

int main(int argc, char **argv)
{
    err_setarg0(argv[0]);
    if (argc > 2)
        err_usage("[directory]");
    char *dir = ".";
    if (argc == 2)
        dir = argv[1];
    DIR *dp = opendir(dir);
    if (dp == NULL)
        err_syserr("failed to open directory '%s': ", dir);
    char *name_0 = 0;
    int counter = 0;
    struct dirent *name;
    while ((name = readdir(dp)) != NULL)
    {
        if (++counter % 2 == 1)
        {
            if ((name_0 = strdup(name->d_name)) == NULL)
                err_syserr("failed to duplicate name '%s': ", name->d_name);
        }
        else
        {
            printf("(%s, %s)\n", name_0, name->d_name);
            free(name_0);
            name_0 = NULL;
        }
    }
    if (counter % 2 == 1)
        printf("(%s, %s)\n", name_0, "NULL");
    free(name_0);
    closedir(dp);
    return 0;
}

stderr.h中声明的函数全部启动err_并大大简化了错误报告。您可以在https://github.com/jleffler/soq/tree/master/src/libsoq的GitHub上找到他们的代码。)