如何仅计算路径中的目录数

How to count only the number of directories from a path

我试图只计算路径中的目录,但它不起作用。所以,我不想给文件和目录都编号,我只想要目录。请问你能帮帮我吗? 代码:

int listdir(char *dir) {
    struct dirent *dp;
    struct stat s;
    DIR *fd;
    int count = 0;

    if ((fd = opendir(dir)) == NULL) {
        fprintf(stderr, "listdir: can't open %s\n", dir);
    }
    while ((dp = readdir(fd)) != NULL) {
        if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
            continue;
        stat(dp->d_name, &s);
        if (S_ISDIR(s.st_mode))
        count++;
    }
    closedir(fd);
    return count;
}

我想你想要...

  • 用 C 编写
  • 计算路径中目录的数量。
  • 计数函数将 returns int 值。

我不知道你的环境,所以这只是一个示例解决方案。

如果你会用glob,那么统计目录数就简单多了。即:main.c

#include <stdio.h>
#include <glob.h>
#include <string.h>

#define MAX_PATH 1023

int countDirectories(char* dir)
{
    char path[MAX_PATH] = "";
    strcat(path, dir);
    strcat(path, "/*");

    glob_t globbuf;
    long i, count = 0;

    if (glob(path, GLOB_NOSORT | GLOB_ONLYDIR, NULL, &globbuf) == 0)
    {
        count = globbuf.gl_pathc;
        for (i = 0; i < globbuf.gl_pathc; i++)
        {
            count += countDirectories(globbuf.gl_pathv[i]);
        }
    }
    globfree(&globbuf);

    return count;
}

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

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

    printf("there are %d directories.\n", count);

    return 0;
}

您可以这样尝试:

> gcc main.c -o testglob
> ./testglob /path/to/target/dir

然后你会收到这样的输出:

path = /path/to/target/dir/*, there are N directories

谢谢。

您的 stat() 调用将失败,因为您不在正确的目录中。这可以通过更改当前目录或生成完整路径并将 stat 作为参数提供来解决。

一些 Unix,您可以通过查看 struct dirent,d_type 字段

来优化统计调用
int listdir(char *dir) {
    struct dirent *dp;
    struct stat s;
    DIR *fd;
    int count = 0;

    if ((fd = opendir(dir)) == NULL) {
        fprintf(stderr, "listdir: can't open %s\n", dir);
    }
    chdir (dir); /* needed for stat to work */
    while ((dp = readdir(fd)) != NULL) {
        if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
            continue;
#ifdef _DIRENT_HAVE_D_TYPE
        switch (dp->d_type)
        {
          case DT_UNKNOWN:
            stat(dp->d_name, &s);
            if (S_ISDIR(s.st_mode)) count++;
            break;
          case DT_DIR:
            count++;
            break;
        }
#else
        stat(dp->d_name, &s);
        if (S_ISDIR(s.st_mode)) count++;
#endif            
    }
    closedir(fd);
    return count;
}