C - 忽略子目录名,只打印文件名

C - Ignore subdirectories names and only print files names

使用这段代码,我可以递归地打印给定路径中的所有文件和子目录。

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

这是代码:

#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;
}

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

  • S_ISREG(): 普通文件
  • S_ISDIR():目录文件
  • S_ISCHR(): 字符特殊文件
  • S_ISBLK(): 块特殊文件
  • S_ISFIFO(): 管道或先进先出 -S_ISLNK(): 象征性的
  • S_ISSOCK(): link 套接字

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

#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 环境高级编程》一书:

Given a pathname, the stat function returns a structure of information about the named file. The fstat function obtains information about the file that is already open on the descriptor fd. The lstat function is similar to stat, but when the named file is a symbolic link, lstat returns information about the symbolic link, not the file referenced by the symbolic link.

您可以尝试以下操作:

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 宏。相反,我们必须在逻辑上 AND st_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:  ... 
    }