如何在c中确定linux中的目录或文件

tra*_*loo 1 c linux

我想只打印文件名而不打印目录名称.所以,我实现了这个功能

void list_file(char* directory){
  DIR *d;
  struct dirent *dir;
  d = opendir(directory);
  if (d)
  {
    while ((dir = readdir(d)) != NULL)
    {
        printf("%c", dir->d_name[(int)strlen(dir->d_name)]);
        if(dir->d_name[(int)strlen(dir->d_name)-2] != '/')
            printf("%s\n", dir->d_name);
    }

    closedir(d);
  }
}
Run Code Online (Sandbox Code Playgroud)

我检查了目录名以'/'字符结尾.所以,我检查过如果名字的末尾有'/'字符,不要打印那个名字,但是当我运行该功能时,所有这些都打印在选定的目录中?

你能告诉我如何检查目录名称的结尾?

mis*_*mer 8

您正在寻找的是stat其中一种变体.具体看看st_mode领域struct stat.你感兴趣的宏是S_ISDIR(x).

在下面找到演示您想要的修改后的代码:

void list_file(char* directory) {
  DIR *d;
  struct dirent *dir;
  int dir_len = strlen(directory);
  char* path = malloc(dir_len + NAME_MAX + 2); // +2, 1 for '/' and 1 for '\0'
  if(path == NULL) {
    fprintf(stderr, "malloc failed\n");
    return;
  }
  strcpy(path, directory);
  if(path[dir_len-1] != '/') {
    path[dir_len] = '/';
    dir_len++;
  }
  d = opendir(directory);
  if (d) {
    while ((dir = readdir(d)) != NULL)
    {
      struct stat buf;
      strcpy(&path[dir_len], dir->d_name);
      if(stat(path, &buf) < 0) {
        fprintf(stderr, "error\n");
      }
      else {if(!S_ISDIR(buf.st_mode)) {
          printf("%s\n", dir->d_name);
        }
      }
    }

    closedir(d);
  }
  free(path);
}
Run Code Online (Sandbox Code Playgroud)

我删除了你的第一个打印,因为它正在打印字符串的空终止字符.

更新:

正如我们在处理Linux时所说的那样,你可以使用d_type字段struct dirent(它不是POSIX的一部分,而是Linux的一部分).

有了这个说,代码将如下.

void list_file(char* directory){
  DIR *d;
  struct dirent *dir;

  d = opendir(directory);
  if (d) {
    while ((dir = readdir(d)) != NULL)
    {
      struct stat buf;
      if(dir->d_type == DT_DIR) {
         printf("%s\n", dir->d_name);
      }
    }

    closedir(d);
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个更清洁,没有必要malloc.

  • 除非 `directory` 是“.”,否则这将不起作用。- 当前目录。根据http://linux.die.net/man/3/readdir,“struct dirent”的“d_name”成员只是基本文件名,而不是包含前面目录的整个路径 - 它只是“文件名” ”而不是“/完整/路径/到/文件名”。 (2认同)

Rak*_*ish 5

stat, fstat, lstat根据需要尝试使用其中之一。这用于获取文件状态。

用法:

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
Run Code Online (Sandbox Code Playgroud)
  1. stat()统计path指向的文件并填充buf。

  2. lstat() 与 stat() 相同,但如果路径是符号链接,则对链接本身进行统计,而不是对其引用的文件进行统计。

  3. fstat() 与 stat() 相同,只是要统计的文件由文件描述符 fd 指定。

它们都返回一个stat结构,其中包含以下字段:

struct stat {
               dev_t     st_dev;     /* ID of device containing file */
               ino_t     st_ino;     /* inode number */
               mode_t    st_mode;    /* protection */
               nlink_t   st_nlink;   /* number of hard links */
               uid_t     st_uid;     /* user ID of owner */
               gid_t     st_gid;     /* group ID of owner */
               dev_t     st_rdev;    /* device ID (if special file) */
               off_t     st_size;    /* total size, in bytes */
               blksize_t st_blksize; /* blocksize for filesystem I/O */
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
               time_t    st_atime;   /* time of last access */
               time_t    st_mtime;   /* time of last modification */
               time_t    st_ctime;   /* time of last status change */
           };
Run Code Online (Sandbox Code Playgroud)

从此尝试做:

buf.st_mode & S_IFMT                #assuming you have defined struct stat buf;
Run Code Online (Sandbox Code Playgroud)

比较该值以S_IFDIR检查它是否是目录。

更多请参考:man 2 stat

使用struct stat也可以为您提供帮助,因为它包含文件的许多不同信息。