简体   繁体   中英

search and print all the files and subfolders of a directory

I have to write a C program that takes a directory as an argument, recursively prints a tree with all the files and subdirectories. I do not know how to do this, can you help me? Thanks a lot.

In pure standard C, you cannot do that, since the C11 standard n1570 does not mention directories .

You need some operating system specific things. On Linux, look into nftw(3) . It uses lower level stuff like opendir(3) , readdir(3) , closedir , stat(2) that you might use directly.

On Windows, the API to handle directories is very different.

Some frameworks like Poco , Boost , Qt , ... try to define some common abstraction on directories working on several OSes. But the precise notion of directory and file is different on Windows and on Unix or Linux. See also this .

opendir(),readdir()and closedir() based implementations almost never handle the cases where directories or files are moved, renamed, or deleted during the tree traversal. nftw() should handle them correctly

For file tree walk there are two functions. ftw() and nftw(). ftw() walks through the directory tree that is located under the directory dirpath, and calls fn() once for each entry in the tree. By default, directories are handled before the files and sub-directories they contain (preorder traversal).

*int ftw(const char *dirpath,int (*fn) (const char *fpath, const struct stat sb,int typeflag),int nopenfd);

The function nftw() is the same as ftw(), except that it has one additional argument, flags, and calls fn() with one more argument, ftwbuf. This flags argument is formed by ORing zero or more of the following flags:

int nftw(const char *dirpath,int (*fn) (const char *fpath, const struct stat *sb,int typeflag, struct FTW *ftwbuf), int nopenfd, int flags);

These functions return 0 on success, and -1 if an error occurs.

The following program traverses the directory tree under the path named in its first command-line argument, or under the current directory if no argument is supplied. It displays various information about each file.

   #define _XOPEN_SOURCE 500
   #include <ftw.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <stdint.h>

   static int display_info(const char *fpath, const struct stat *sb,
   int tflag,struct FTW *ftwbuf)
   {
    printf("%-3s %2d %7jd   %-40s %d %s\n",
    (tflag == FTW_D) ?   "d"   : (tflag == FTW_DNR) ? "dnr" :
    (tflag == FTW_DP) ?  "dp"  : (tflag == FTW_F) ?   "f" :
    (tflag == FTW_NS) ?  "ns"  : (tflag == FTW_SL) ?  "sl" :
    (tflag == FTW_SLN) ? "sln" : "???",
    ftwbuf->level, (intmax_t) sb->st_size,
    fpath, ftwbuf->base, fpath + ftwbuf->base);
    return 0;           /* To tell nftw() to continue */
    }

   int main(int argc, char *argv[])
   {
   int flags = 0;

  if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags)
        == -1) {
    perror("nftw");
    exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
  }

Basile is right. It depends on your operating system. There are some programs written in order to print directories/files other than ntfw , called as walking directories in POSIX. For example,

#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>

void listdir(const char *name, int indent)
{
    DIR *dir;
    struct dirent *entry;

    if (!(dir = opendir(name)))
        return;

    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_DIR) {
            char path[1024];
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                continue;
            snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
            printf("%*s[%s]\n", indent, "", entry->d_name);
            listdir(path, indent + 2);
        } else {
            printf("%*s- %s\n", indent, "", entry->d_name);
        }
    }
    closedir(dir);
}

int main(void) {
    listdir(".", 0);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM