1

我正在编写一个代码来使用depth first算法遍历目录。问题是程序没有显示任何内容并给出Segmentation Fault error. 我试图调试它,但它毫无价值,因为我还在学习东西。所以现在我需要专家的帮助。这是代码:

void func(char path[]);

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

    scanf("%s",buf);
    func(buf);
    return 0;
}

void func(char path[]) {
    DIR *dirp;
    struct stat states;
    struct dirent *direntp;
    printf("Inside\n");
    dirp=opendir(path);
    stat(path, &states);

    while ((direntp=readdir(dirp)) != NULL) {
        if (S_ISDIR(states.st_mode)) {
            printf("Calling Func\n");
            func(direntp->d_name);
            chdir("..");
        } else if (!S_ISDIR(states.st_mode)) {
            printf("  %s\n", direntp->d_name);
        } else if (!strcmp(direntp->d_name, ".") || !strcmp(direntp->d_name, "..")) {
            continue;
        }
    }
    return ;
}
4

2 回答 2

1

在 func 里面,在 while 前面,放上:

dirp=opendir (path);
if (!dirp)
  return;

而且,顺便说一句,它的int main (int argc, char *argv[])

于 2012-12-15T15:51:36.677 回答
0

用于调试打印,打印到stderr; 它是行缓冲的,因此看起来更可靠。

概括地说,您的功能是:

void func(char path[])
{
    DIR *dirp;
    struct stat states;
    struct dirent *direntp;
    printf("Inside\n");
    dirp=opendir(path);
    stat(path,&states);

    while ((direntp = readdir(dirp)) != NULL)
    {
        if (S_ISDIR(states.st_mode))
        {
            printf("Calling Func\n");
            func(direntp->d_name);
            chdir("..");
        }
        else if (!S_ISDIR(states.st_mode))
        {
            printf("  %s\n",direntp->d_name);
        }
        else if (!strcmp(direntp->d_name,".") || !strcmp(direntp->d_name,".."))
        {
            continue;
        }
    }
}

chdir("..")是不明智的;您既没有chdir()对相关目录进行操作,也没有确保该目录是当前目录的直接子目录,这意味着这段代码将会变得混乱……如果它到达那一点。

您这样做stat(path, &states);但不检查它是否有效。

您这样做dirp = opendir(path);但不检查它是否有效。

您不会stat()在每个条目上都这样做;您不断使用来自 的初始统计信息path。这可能是您测试时的一个目录,因此您然后递归调用该函数,该函数将读取.,这是一个目录,如果您没有先用完指针,​​您可能最终会用完堆栈DIR

即使您stat()对文件进行了排列,您在循环中的测试顺序也是错误的——这是一个非常重要的操作,因为您刚刚读取的名称必须附加到目录的路径中才能形成正确的文件名。你的代码是:

if (is a directory)
else if (is not a directory)
else if (name is . or ..)
else ...missing...

首先,theif和以下else if涵盖了所有选项,因此else永远不会执行名称 test 和 final(不存在)。您可能首先需要名称 test (伪代码):

if (name is a "." or "..")
    print "Skipping";
else if (name is a directory)
{
    create "path/name" as string;
    recurse with "path/name";
}
else
    print "Skipping non-directory";

请注意,这总是在每次迭代中打印一些东西。这在调试时非常重要。您不希望代码在执行您不期望的事情时保持安静。

请注意,您不要调用closedir(); 这意味着您将用完目录描述符,获得一个 NULL 值,dirp当您使用它时会崩溃。

请注意,伪代码不包含任何chdir()操作。使用它们时要非常、非常、非常谨慎。了解fchdir().

阅读ftw()nftw(); 有关于这些功能面临的复杂性的注释。

于 2012-12-15T18:57:44.847 回答