Làm thế nào để liệt kê các tệp trong một thư mục trong chương trình C?


88

Tôi đang cố gắng viết một máy chủ ftp trên Linux. Trong vấn đề này, làm cách nào để liệt kê các tệp trong thư mục trên thiết bị đầu cuối bằng chương trình C? Có lẽ tôi có thể sử dụng hàm thực thi để chạy lệnh find nhưng tôi muốn tên tệp là một chuỗi để gửi chương trình khách hàng. Tôi có thể làm cái này như thế nào?

Cảm ơn vì câu trả lời.

Câu trả lời:


175

Một ví dụ, có sẵn cho các hệ thống tuân thủ POSIX:

/*
 * This program displays the names of all files in the current directory.
 */

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

int main(void) {
  DIR *d;
  struct dirent *dir;
  d = opendir(".");
  if (d) {
    while ((dir = readdir(d)) != NULL) {
      printf("%s\n", dir->d_name);
    }
    closedir(d);
  }
  return(0);
}

Lưu ý rằng hoạt động như vậy phụ thuộc vào nền tảng trong C.

Nguồn: http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046380353&id=1044780608


nó là ok bây giờ và rất dễ dàng. Cảm ơn câu trả lời một lần nữa.
cemal

13
hãy xác thực nó nếu bạn thích nó;)
Jean-Bernard Jansen

1
Tuyệt vời, Nhưng nếu chúng ta chỉ muốn pngcác tệp thì sao?
Farsheed

2
@Farsheed: thử cái này .
Fraxtil

Tôi gặp một số vấn đề với điều này. Đầu tiên, "." và ".." xuất hiện ở đầu mọi thư mục, và mặc dù chúng là "thư mục", chúng có loại dir-> d_type được đặt thành DT_REG. Ngoài ra, tôi dường như không nhận được tất cả các tệp ... Có mã "máy quét thư mục" toàn diện hơn ở đâu đó không? Có thể một số người nghèo triển khai "ls"? Tôi cần điều này trên Mac - OS-X
Motti Shneor

35

Một bổ sung nhỏ cho câu trả lời của JB Jansen - trong readdir()vòng lặp chính, tôi sẽ thêm điều này:

  if (dir->d_type == DT_REG)
  {
     printf("%s\n", dir->d_name);
  }

Chỉ cần kiểm tra xem đó có thực sự là tệp hay không, không phải liên kết (sym), thư mục hay bất cứ thứ gì.

LƯU Ý: thêm về struct direnttrong libctài liệu hướng dẫn .


6
Chỉ là một bên: Không phải tất cả các nền tảng sẽ điền vào d_type, nhưng Linux và BSD sẽ điền vào (tôi biết câu hỏi được gắn thẻ Linux, chỉ cần mở rộng câu trả lời một chút); ngay cả khi đó, không phải tất cả các hệ thống tệp đều được hỗ trợ đồng nhất , tuy nhiên nó sẽ hoạt động với hầu hết các FS.
omninonsense,

11

Đây là một chương trình hoàn chỉnh cách liệt kê đệ quy nội dung của thư mục:

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

#define NORMAL_COLOR  "\x1B[0m"
#define GREEN  "\x1B[32m"
#define BLUE  "\x1B[34m"



/* let us make a recursive function to print the content of a given folder */

void show_dir_content(char * path)
{
  DIR * d = opendir(path); // open the path
  if(d==NULL) return; // if was not able return
  struct dirent * dir; // for the directory entries
  while ((dir = readdir(d)) != NULL) // if we were able to read somehting from the directory
    {
      if(dir-> d_type != DT_DIR) // if the type is not directory just print it with blue
        printf("%s%s\n",BLUE, dir->d_name);
      else
      if(dir -> d_type == DT_DIR && strcmp(dir->d_name,".")!=0 && strcmp(dir->d_name,"..")!=0 ) // if it is a directory
      {
        printf("%s%s\n",GREEN, dir->d_name); // print its name in green
        char d_path[255]; // here I am using sprintf which is safer than strcat
        sprintf(d_path, "%s/%s", path, dir->d_name);
        show_dir_content(d_path); // recall with the new path
      }
    }
    closedir(d); // finally close the directory
}

int main(int argc, char **argv)
{

  printf("%s\n", NORMAL_COLOR);

    show_dir_content(argv[1]);

  printf("%s\n", NORMAL_COLOR);
  return(0);
}

4

Đoạn mã dưới đây sẽ chỉ in các tệp trong thư mục và loại trừ các thư mục trong thư mục nhất định khi đang duyệt.

#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include<string.h>
int main(void)
{
    DIR *d;
    struct dirent *dir;
    char path[1000]="/home/joy/Downloads";
    d = opendir(path);
    char full_path[1000];
    if (d)
    {
        while ((dir = readdir(d)) != NULL)
        {
            //Condition to check regular file.
            if(dir->d_type==DT_REG){
                full_path[0]='\0';
                strcat(full_path,path);
                strcat(full_path,"/");
                strcat(full_path,dir->d_name);
                printf("%s\n",full_path);
            }
        }
        closedir(d);
    }
    return(0);     
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.