1. 程式人生 > >C語言如何實現遍歷目錄的功能

C語言如何實現遍歷目錄的功能

如何用C語言實現linux下的ls命令

  首先我講一下寫這篇東西的目的。我覺得對於很多linux新手。尤其是在自學的同學。最好的學習的方法就是通過具體的例子。通過一個實踐的例子,在學習相關的知識點的同時,就把它們應用到這例子中。這樣不僅知道了原理。也知道了怎麼去應用。下面就開始用一個常用的命令”ls”開始。所有的東西都是從最基本的原理開始。一步步來教你怎麼實踐出一個命令
    (一)ls命令簡單介紹
    第一步當然是要明白ls究竟是做什麼的。如果你要做一個東西卻不知道要用來幹嘛。會不會很搞笑?所以下面就簡單的介紹ls命令的作用和怎麼使用

    1.Ls可以列出檔名和檔案的屬性
    在命令列輸入ls:

    ls 命令.jpg

    Ls的預設動作是找出當前所有檔案的檔名。按字典排序後輸出。
    Ls還能顯示其他的資訊。如果加上-l就會列出每個檔案的詳細資訊。也叫ls的長格式:

    ls -l命令.jpg


    2.        列出指定目錄或檔案的資訊
    Linux系統中會有很多目錄。每個目錄中又會有很多檔案。如果要列出一個非當前目錄的內容或者是一個特定檔案的資訊,則需要在引數中給出目錄名或檔名。如:
    ls /tmp //列出/tmp目錄中各檔案的檔名
    ls – docs //列出docs目錄中各檔案的屬性
    ls *.c //列出當前目錄下與*.c匹配的檔案,即當前目錄下所有以.c為字尾的檔案

    3.        經常用到的命令列選項
    ls -l 在前面已經提到過,-l就是輸出檔案詳細的資訊。也叫長格式;
    ls -a 列出的內容包含以“.“開頭的讓檔案,即所謂有隱藏檔案
    ls –lu 顯示最後訪問時間
    ls –t 輸出時按時間排序
    ls –F 顯示檔案型別

    ls 命令的引數選項非常多,大多也可以組合使用。所以還是比較複雜的。但是我們第一步要實現的就是它最基本的功能:列出當前目錄下的所有檔案或子目錄。

    (二)學習必備的知識

    既然是列出檔案和目錄,那麼肯定是和linux檔案系統有關係的,所以要寫ls命令,至少要對檔案系統的基本原理有一定的瞭解。為了不至於使這個帖子內容過於複雜,我把這方面的知識介紹單獨開了一個帖子:
    linux 檔案系統詳解

    如果你對這些已經有所瞭解。就會知道linux下的檔案都是以/為根目錄的樹型結構,雖然linux下有普通檔案、目錄檔案、連結檔案、裝置檔案、管道檔案這幾種型別。但連結檔案、裝置檔案、管道檔案都可以當做普通檔案看待,那實際也就只要區分普通檔案和目錄檔案這兩種了。而目錄檔案的內容就是它所包含所有檔案和子目錄的一個列表,所以只要開啟目錄檔案並讀取對應目錄塊裡的那個列表資料,就可以得到些目錄下所有檔案和子目錄的名稱了。其實這個流程簡單,就是:開啟目錄->讀取內容->顯示檔名稱->關閉開啟的目錄。用虛擬碼流程表示如下:
    Mani(){
    Opendir
    While(readdir)
    Print d_name
    Closedir;
    }
     那麼現在的問題是用什麼函式去開啟並讀目錄呢?又是怎麼樣來讀出資料呢?這裡介紹是的opendir 和readdir,但是可能對於一些新手來說,就算知道了函式名稱也不一定知道怎麼用。別急,下一步就是教你怎麼去查相應函式的幫助資料。
    linux下檢視幫助手冊的命令是man,關於man的詳細介紹在這個帖子裡我有詳細介紹:linux 幫助手冊頁命令 man詳解 如果對這方面還不是很清楚的可以先去學習一下。
    好了,如果你已經明白man的用法,我們就開始檢視opendir和readdir的用法
    我們在命令列輸入:
    # man 3 opendir

怎樣使用C語言列出某個目錄下的檔案?

轉載自:http://see.xidian.edu.cn/cpp/html/1548.html

C語言本身沒有提供象dir_list()這樣的函式來列出某個目錄下所有的檔案。不過,利用C語言的幾個目錄函式,你可以自己編寫一個dir_list()函式。   

首先,標頭檔案dosh定義了一個find_t結構,它可以描述DOS下的檔案資訊,包括檔名、時間、日期、大小和屬性。其次,C編譯程式庫中有_dos_findfirst()_dos_findnext()這樣兩個函式,利用它們可以找到某個目錄下符合查詢要求的第一個或下一個檔案。   

dos_findfirst()函式有三個引數,第一個引數指明要查詢的檔名,例如你可以用“*.*”指明要查詢某個目錄下的所有檔案。第二個引數指明要查詢的檔案屬性,例如你可以指明只查詢隱含檔案或子目錄。第三個引數是指向一個find_t變數的指標,查詢到的檔案的有關資訊將存放到該變數中。   

dos_findnext()函式在相應的目錄中繼續查詢由_dos_findfirst()函式的第一個引數指明的檔案。_dos_findnext()函式只有一個引數,它同樣是指向一個find_t變數的指標,查詢到剛檔案的有關資訊同樣將存放到該變數中。

利用上述兩個函式和find_t結構,你就可以遍歷磁碟上的某個目錄,並列出該目錄下所有的檔案,請看下例:   

#include <stdio.h>

#include <direct.h>

#include <dos.h>

#include <malloc.h>

#include <memory.h>

#include <string.h>

typedef struct find_t FILE_BLOCK

void main(void);

void main(void)

{

      FILE_BLOCK f-block;         /* Define the find_t structure variable * /

      int   ret_code;             / * Define a variable to store the return codes * /

      / * Use the "*.*" file mask and the 0xFF attribute mask to list

           all files in the directory, including system files, hidden

           files, and subdirectory names.  * /

      ret_code = _dos_findfirst(" *. * ", 0xFF, &f_block);

      /* The _dos_findfirst() function returns a 0 when it is successful

         and has found a valid filename in the directory.  * /

     while (ret_code == 0)

     {

          /* Print the file's name * /

          printf(" %-12s\n, f_block, name);

          / * Use the -dos_findnext() function to look

               for the next file in the directory.  * /

          ret_code = _dos_findnext (&f_block);

     }

     printf("\nEnd of directory listing. \n" );

}

//-------------------------------------------------

linux下用C語言歷遍目錄( C語言列出目錄)

轉載自:http://blog.sina.com.cn/s/blog_49ea99e10100f40z.html

linux下歷遍目錄的方法一般是這樣的:

開啟目錄-》讀取-》關閉目錄

相關函式是(函式原形)

opendir -> readdir -> closedir

#include <dirent.h>

DIR *opendir(const char *dirname);

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

#include <dirent.h>

int closedir(DIR *dirp);

dirent.h這個標頭檔案,包括了目錄的一些函式。

opendir用於開啟目錄,是類似於流的那種方式,返回一個指向DIR結構體的指標,他的引數*dirname是一個字元陣列或者字串常量。

readdir函式用於讀取目錄,他只有一個引數,這個引數主要是opendir返回的結構體指標。

dirent的結構如下定義

                   struct dirent

                   {

                       long d_ino;                     

                       off_t d_off;                    

                       unsigned short d_reclen;        

                       char d_name [NAME_MAX+1];       

                   }

結構體中d_ino存放的是該檔案的結點數目;

d_off 是檔案在目錄中的編移;

short d_reclen是這個檔案的長度;

程式如下:

#include apue.h"

#include <dirent.h>

int

main(int argc ,char *argv[])

{

       DIR         *dp;

       struct dirent   *dirp;

       if(argc!=2)

             err_quit("usage: ls directory_name");

       if((dp=opendir(argv[1]))==NULL)

              err_sys("can't open %s",argv[1]);

      while((dirp=readdir(dp))!=NULL)

              printf("%s\n",dirp->d_name);

     closedir(dp);

     exit(0);

}

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <dirent.h>

void print_usage(void);

void print_usage(void)

{

printf("Usage: test dirname\n");

}

int main(int argc,char *argv[])

{

DIR * dp;

struct dirent *filename;

if (argc < 2)

{

       print_usage();

       exit(1);

}

dp = opendir(argv[1]);

if (!dp)

{

       fprintf(stderr,"open directory error\n");

       return 0;

}

while (filename=readdir(dp))

{

       printf("filename:%-10s\td_info:%ld\t d_reclen:%us\n",

         filename->d_name,filename->d_ino,filename->d_reclen);

}

closedir(dp);

return 0;

}

sudo gcc readdir.c

 ./a.out /home/growliming

結果如下:

filename:APUE.chm      d_info:16746     d_reclen:20s

filename:src.tar.gz    d_info:1063454     d_reclen:24s

filename:c             d_info:24536     d_reclen:16s

filename:apue.2e       d_info:32874     d_reclen:20s

filename:..            d_info:16353     d_reclen:16s

filename:.             d_info:16708     d_reclen:16s

//-----------------------------------------------------------------

c語言列出資料夾中的檔案

轉載自:http://blog.csdn.net/gotoxy/article/details/1872332

/*  TC2.0 下編譯*/

#include "stdio.h"

#include "stdlib.h"

#include "dir.h"

#include "dos.h"

#define wait() getch()

/*

============目錄函式(原型宣告所在標頭檔案為dir.hdos.h================

int     chdir(char *path) 使指定的目錄path(如:"C://WPS")變成當前的工作目錄,

         功返回0

int findfirst(char *pathname,struct ffblk *ffblk,int attrib)查詢指定的檔案,成功

     返回0

     pathname為指定的目錄名和檔名,"C://WPS//TXT"

     ffblk為指定的儲存檔案資訊的一個結構,定義如下:

    ┏━━━━━━━━━━━━━━━━━━┓

    ┃struct ffblk                        

    ┃{                                   

    ┃ char ff_reserved[21]; //DOS保留字  ┃

    ┃ char ff_attrib;       //檔案屬性   ┃

    ┃ int  ff_ftime;        //檔案時間   ┃

    ┃ int  ff_fdate;        //檔案日期   ┃

    ┃ long ff_fsize;        //檔案長度   ┃

    ┃ char ff_name[13];     //檔名     ┃

    ┃}                                   

    ┗━━━━━━━━━━━━━━━━━━┛

     attrib為檔案屬性,由以下字元代表

    ┏━━━━━━━━━┳━━━━━━━━┓

    ┃FA_RDONLY 只讀檔案┃FA_LABEL  卷標號┃

    ┃FA_HIDDEN 隱藏檔案┃FA_DIREC  目錄  ┃

    ┃FA_SYSTEM 系統檔案┃FA_ARCH   檔案  ┃

    ┗━━━━━━━━━┻━━━━━━━━┛

    例:

    struct ffblk ff;

    findfirst("*.wps",&ff,FA_RDONLY);

int   findnext(struct ffblk *ffblk)      取匹配finddirst的檔案,成功返回0

*/

void formatExt(char *dstr,char *sstr)

{

    sscanf(sstr,"[^///:*?/"<>|]",dstr);

}

typedef int (*METHOD)();

int enum_allFile(METHOD method,char *dir,char *type,int filter)

{/*

method==NULL 僅顯示檔名

dir==NULL 當前資料夾

*/

    static struct ffblk ff;

    static int ct,run_method;

 run_method=0;

    if(type!=NULL){

        if(dir!=NULL) {

            if(chdir(dir)){

                puts("folder can't found!");

                wait();

                exit(1);

            }

        }

        formatExt(type,type);

        if(findfirst(type,&ff,filter)) {

            puts("can't find file!");

            ct=0;

            return 0;

        }

        ct=1;

  run_method=1;

    }

    else {

            if(findnext(&ff) ==0){

                ct++;

    run_method=1;

            }

            else return ct;

    }

 if(run_method){

  if(method!=NULL) method(ff.ff_name);

  else printf("/n%s",ff.ff_name);

 }

    enum_allFile( method,NULL, NULL, 0);

    return ct;

}

void TestFunc(char *fname)

{

puts(fname);

}

int main()

{

 int ct;

 ct=enum_allFile( TestFunc, NULL, "*.c", FA_RDONLY | FA_HIDDEN | FA_SYSTEM );/* */

 printf("/n--------------%d-------------/n",ct);

 wait();

 return 0;

}

Linux中用C語言實現目錄檢索和返回所有檔案

轉載自:http://blog.sina.com.cn/s/blog_48a83572010002p6.html

    大家都知道,使用遞迴呼叫的方法可以完成對指定目錄及其所有子目錄的遍歷.這在WINDOW下是不難實現的.而在LINUX,由於我沒有找到相關的例項.所以自己動手做了一個.請大家指正.

/*

 * FUNCTION     : ReadPath

 * ABSTRACT     : Get the file name from path and is't child path

 * PARAMETER    :

 *       char* path      

 *       char file[FILE_CNT_MAX][256]       the all files path and name int the specified path

 * RETURN       :

 *       0       OK

 *      -1       FALSE

 * CREATE       : 2006-01-05    ZHANG.JINCUN

 * NOTE         :

 */

int g_iFileCnt = 0;

int ReadPath(char* path, char file[][256], char* filefmt)

{

    DIR * pdir;

    struct dirent * ptr;

    char newpath[256];

    struct stat filestat;

    if(stat(path, &filestat) != 0){

        printf("The file or path(%s) can not be get stat!\n", newpath);

        return -1;

    }

    if((filestat.st_mode & S_IFDIR) != S_IFDIR){

        printf("(%s) is not be a path!\n", path);

        return -1;

    }

    pdir =opendir(path);

    while((ptr = readdir(pdir))!=NULL)

    {

        if(g_iFileCnt + 1 > FILE_CNT_MAX){

            printf("The count of the files is too much(%d > %d)!\n", g_iFileCnt + 1, FILE_CNT_MAX);

            break;

        }

        if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)  continue;

        sprintf(newpath,"%s/%s", path,ptr->d_name);

        if(stat(newpath, &filestat) != 0){

            printf("The file or path(%s) can not be get stat!\n", newpath);

            continue;

        }

        /* Check if it is path. */

        if((filestat.st_mode & S_IFDIR) == S_IFDIR){

            if(ReadPath(newpath, file, filefmt) != 0){

                printf("Path(%s) reading is fail!\n", newpath);

                continue;

            }

        }else if((filestat.st_mode & S_IFREG) == S_IFREG){

            if(filefmt[0] != '\0'){

                char* p;

                if((p = strrchr(ptr->d_name,'.')) == 0) continue;

                char fileformat[64];

                char* token;

                strcpy(fileformat, filefmt);        

                if((token = strtok( fileformat,";")) == NULL){

                    strcpy(file[g_iFileCnt], newpath);

                    g_iFileCnt++;

                    continue;

                }else{

                    if(strcasecmp(token,p) == 0){

                        strcpy(file[g_iFileCnt], newpath);

                        g_iFileCnt++;

                        continue;

                    }

                }

                while((token = strtok( NULL,";")) != NULL){

                    if(strcasecmp(token,p) == 0){

                        strcpy(file[g_iFileCnt], newpath);

                        g_iFileCnt++;

                        continue;

                    }                }

            }else{

                strcpy(file[g_iFileCnt], newpath);

                g_iFileCnt++;

            }

        }

    }

    closedir(pdir);

    return 0;   

}

    在上面的ReadPath()函式中,引數char* path是你要檢索的目錄,其內部可以有子目錄;char file[][256]是檢索結果,存放所有匹配的檔名;char* filefmt是你需要返回檔案的型別,例如".cc;.c;.h".

    請大家幫我看看這個函式的效能,也供大家參考使用.本函式已經在LINUX上執行通過.

    本函式本人所有.請勿商業使用.謝謝!

相關推薦

linux平臺下基於C語言實現檔案目錄

#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h&g

c語言實現字串並分割成陣列

遍歷字串 int sepcharbydh(char *in, char caOut[200][256]) { char *p, *p2; long lCount; long m = 0; lCount = 0; if

C語言如何實現目錄功能

如何用C語言實現linux下的ls命令   首先我講一下寫這篇東西的目的。我覺得對於很多linux新手。尤其是在自學的同學。最好的學習的方法就是通過具體的例子。通過一個實踐的例子,在學習相關的知識點的同時,就把它們應用到這例子中。這樣不僅知道了原理。也知道了怎麼去應用。下面就開始用一個常用的命令”ls”

Python遞歸實現目錄

遞歸 內容 imp join light sdi def 是否 tdi import os filePath = "/Users/busensei/wzy/filePath/" def read(filePath, n): it = os.listdir(f

牛客網:java入門實現目錄

專案介紹 遍歷目錄是操作檔案時的一個常見需求。比如寫一個程式,需要找到並處理指定目錄下的所有JS檔案時,就需要遍歷整個目錄。該專案教會你如何使用流式程式設計和lambda表示式,幫助你進一步熟悉java8特性,並且通過它實現目錄遍歷。  

[領卓教育]用C語言實現ls以及ls-功能

各位程式設計師在自己的虛擬機器裡一定沒少執行過“ls”這個功能吧,這個程式碼就是實現了ls和ls-l功能,話不多說,上程式碼。 實現程式碼 int process_ls(char * path) { DIR * dirp; struct dire

c語言指標二維陣列

#include <stdio.h> void bian(int row,int col,int *a) { int i,j; for(i=0;i<row;i++) for(j=0;j<col;j++) printf("%d

c語言實現一個strcat函式功能相同的函式

extern char *strcat(char *dest,char *src); 把src所指字串新增到dest結尾處(覆蓋dest結尾處的'\0')並新增'\0'。 #include "std

c語言實現鏈棧基本功能

typedef struct node{ int data; node *next; }Node,*pNode; typedef struct{ pNode top; int count; }LinkStack,*pLinkStack; 注意:(1).首先定義節點結構體

C++11:for_each_file目錄處理檔案

經常我們需要對某個目錄下的所有檔案進行處理,這裡我們需要列出目錄下的檔案,並找出符合要求的檔案,然後才開始真正的處理工作。大部分情況下,這個流程都差不多,只是檔案處理的內容不同,可不可以做一個類似#include<algorithm>中的for_ea

03鄰接矩陣的深度和廣度C語言實現

返回 算法 ++ 其它 連通圖 edge main fin site #include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define

c語言實現 非遞歸先序二叉鏈樹

停止 數據 節點 一個 null front getchar() getc 輸入 1 #include<stdio.h> 2 #include<conio.h> 3 #include<malloc.h> 4 typedef ch

c語言實現按層次(廣度優先)非遞歸二叉鏈樹

child str sizeof att col std 二叉樹 頭結點 oot 1 #include<stdio.h> 2 #include<conio.h> 4 #include<malloc.h> 5 typedef cha

C語言實現windows進程

nbsp creat ret code 信息 S3 使用 函數 ID #include <windows.h> #include <tlhelp32.h> //進程快照函數頭文件 #include <stdio.h>

c語言實現用指標二維陣列

1 #include <stdio.h> 2 void bian(int row,int col,int *a) 3 { 4 int i,j; 5 for(i=0;i<row;i++) 6 for(j=0;j<col;j++) 7

樹的三種方式(C語言實現

//************************************************************************* // 【前序】遍歷演算法 //二叉樹不空,先訪問根結點,然後前序遍歷左子樹,再前序遍歷右子樹 //***********************

[linux]二叉樹的建立及其遞迴C語言實現)

基礎知識 二叉樹的特點: 每一個節點最多有兩棵子樹,所以二叉樹中不存在度大於2的節點,注意,是最多有兩棵,沒有也是可以的 左子樹和右子樹是有順序的,次序不能顛倒,這點可以在哈夫曼編碼中體現, 順序不同編碼方式不同 -即使樹中某個節點中只有一個子樹的花,也要區分它是左子樹還是右子樹

C語言實現序列構造二叉樹

 程式需要包含二叉樹的基本運算演算法,我在之前的文章中已經寫過,詳見:C語言實現二叉樹各種基本運算的演算法 #define "btree.cpp" //包含二叉樹的基本運算演算法,詳見文章頂部連結 #define MaxWidth 40 /* 由中序遍歷序列構造二叉樹 */

二叉樹後序(遞迴與非遞迴)演算法及C語言實現

二叉樹後序遍歷的實現思想是:從根節點出發,依次遍歷各節點的左右子樹,直到當前節點左右子樹遍歷完成後,才訪問該節點元素。 圖 1 二叉樹   如圖 1 中,對此二叉樹進行後序遍歷的操作過程為: 從根節點 1 開始,遍歷該節點的左子樹(以節點 2 為根節點); 遍歷節點 2 的左子樹(以節點 4 為根

二叉樹中序(遞迴和非遞迴)演算法及C語言實現

二叉樹中序遍歷的實現思想是: 訪問當前節點的左子樹; 訪問根節點; 訪問當前節點的右子樹; 圖 1 二叉樹   以圖  1 為例,採用中序遍歷的思想遍歷該二叉樹的過程為: 訪問該二叉樹的根節點,找到 1; 遍歷節點 1 的左子樹,找到節點 2; 遍歷節點 2 的左子樹,找到節點 4;