zoukankan      html  css  js  c++  java
  • C语言如何实现遍历目录的功能

    如何用C语言实现linux下的ls命令

    转载自:CND8学院(http://school.cnd8.com/c/jiaocheng/60408.htm)


     

      首先我讲一下写这篇东西的目的。我觉得对于很多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上运行通过.

        本函数本人所有.请勿商业使用.谢谢!

  • 相关阅读:
    Codeforces 678E 状压DP
    Codeforces 667C DP
    POJ 3017 DP + 单调队列 + 堆
    Codeforces 1154F (DP)
    Codeforces 1154G 枚举
    Codeforces 1153D 树形DP
    Codeforces 1109E 线段树
    Codeforces 1109C 线段树
    Codeforces 1109D (树的计数问题)
    async/await
  • 原文地址:https://www.cnblogs.com/techstone/p/2761880.html
Copyright © 2011-2022 走看看