假设我有以下代码抽象:
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
无论如何,谢谢。
最佳答案
主要问题是 readdir()
函数在第二次调用时不会保留先前返回的值:
The application shall not modify the structure to which the return value of
readdir()
points, nor any storage areas pointed to by pointers within the structure. The returned pointer, and pointers within the structure, might be invalidated or the structure or the storage areas might be overwritten by a subsequent call toreaddir()
on the same directory stream. They shall not be affected by a call toreaddir()
on a different directory stream.
因此,您必须复制每对条目中第一个条目的名称。想必,您有 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_
开头,大大简化了错误报告。您可以在 GitHub 上找到它们的代码 https://github.com/jleffler/soq/tree/master/src/libsoq 。)
关于C 遍历目录并成对打印条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42263554/