首页 > 解决方案 > C - 忽略子目录名,只打印文件名

问题描述

使用此代码,我可以从给定路径递归打印所有文件和子目录。

我想要的是忽略(不打印)所有子目录名,只打印文件名。

这是代码:

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


void listFilesRecursively(char *basePath)
{
    char path[1000];
    struct dirent *dp;
    DIR *dir = opendir(basePath);

    if (!dir)
        return;

    while ((dp = readdir(dir)) != NULL)
    {
        if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
        {
            strcpy(path, basePath);
            strcat(path, "/");
            strcat(path, dp->d_name);

            listFilesRecursively(path);
            printf("%s\n", path);
        }
    }

    closedir(dir);
}

int main()
{
    char path[100];

    printf("Enter path to list files: ");
    scanf("%s", path);

    listFilesRecursively(path);

    return 0;
}

标签: crecursionfile-listing

解决方案


有一些宏可以告诉您它是什么类型的文件:

  • S_ISREG(): 常规文件
  • S_ISDIR(): 目录文件
  • S_ISCHR(): 字符特殊文件
  • S_ISBLK(): 阻止特殊文件
  • S_ISFIFO(): 管道或 FIFO - S_ISLNK(): 符号
  • S_ISSOCK(): 链接套接字

首先,您可以使用以下功能之一来获取信息:

#include <sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf );
int fstat(int fd, struct stat *buf);
int lstat(const char *restrict pathname, struct stat *restrict buf );
int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag);

来自 Unix 环境中的高级编程一书:

给定路径名,stat 函数返回有关命名文件的信息结构。fstat 函数获取有关已在描述符 fd 上打开的文件的信息。lstat 函数与 stat 类似,但当命名文件是符号链接时,lstat 返回有关符号链接的信息,而不是符号链接引用的文件。

您可以尝试以下方法:

struct stat statbuf;
struct dirent *dirp;
DIR *dp;
int ret, n;
/* fullpath contains full pathname for every file */
if (lstat(fullpath, &statbuf) < 0)
{
    printf("error\n");
    //return if you want
}
if (S_ISDIR(statbuf.st_mode) == 0)
{
   /* not a directory */
}
else
{
   //a directory
}

从历史上看,早期版本的 UNIX 系统没有提供S_ISxxx宏。相反,我们必须在逻辑上将ANDst_mode与掩码S_IFMT进行比较,然后将结果与名称为 的常量进行比较S_IFxxx。大多数系统在文件中定义了这个掩码和相关的常量。

例如:

struct stat *statptr;
if (lstat(fullpath, statptr) < 0)
{
    printf("error\n");
    //return if you want
}
switch (statptr->st_mode & S_IFMT) {
    case S_IFREG:  ...
    case S_IFBLK:  ...
    case S_IFCHR:  ...
    case S_IFIFO:  ...
    case S_IFLNK:  ...
    case S_IFSOCK: ... 
    case S_IFDIR:  ... 
    }

推荐阅读