zoukankan      html  css  js  c++  java
  • 简单find命令的实现

    贴代码:

    /*实现一个简单的find命令:*/
    /*程序思路:首先,用一个单链表将所需要的信息存储起来;其次根据所传入的参数信息,改变节点的状态(若有这个状态,证明该节点就是我们所需要的)
    最后将所需要的信息(文件名)打印出来,释放节点存储空间 */
    /*加上一些信息:若仅仅运行程序(没有输入的参数),则将当前的目录输出,若仅仅只有1个参数(必须为目录)将该目录下的信息输出,接下来根据所给的
    参数信息,执行相应的操作 */

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<string.h>
    #include<dirent.h>
    #include<sys/stat.h>

    char *name;//保存输入的参数(名字)

    /*每一个节点就是一个文件的所有信息*/
    typedef struct Node
    {
    char name[30];//存放文件的名称;
    struct stat info;//存放文件的属性
    int flag;//设置的状态
    struct Node * pNext;//指针域
    }File;

    File *GetInfo(char dirname[]);
    void do_find(int argc, char *argv[], File *pHead);
    void do_free(File *pHead);
    void change_name_flag(File *pHead);
    void print(File *pHead);
    void change_size_flag(File *, long);
    void change_dir_flag(File *);
    void change_cdev_flag(File *);
    void change_bdev_flag(File *);
    void change_gid_flag(File *, long);
    void change_uid_flag(File *, long);


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

    File *pHead = GetInfo(".");
    do_find(argc, argv, pHead);
    print(pHead);

    return 0;
    }

    /*将当前目录里面所需要的所有信息均保存在了所定义的结构体中*/
    File * GetInfo(char dirname[])
    {
    File * pHead = (File *)malloc(sizeof(File));//构造一个头节点
    if (pHead == NULL)
    exit(-1);
    pHead->pNext = NULL;
    File *pTail = pHead;//设置一个尾指针,方便循环体里将所有节点链接

    DIR *dir_ptr;
    struct dirent *direntp;
    if ((dir_ptr = opendir(dirname)) == NULL)//打开目录
    fprintf(stderr, "cannot open %s ", dirname);
    else
    {
    while ((direntp = readdir(dir_ptr)) != NULL)//读取目录
    {
    File *pNew = (File *)malloc(sizeof(File));//生成一个新节点
    if (pNew == NULL)
    exit(-1);
    strcpy(pNew->name, direntp->d_name);/*给数据域赋值*/
    if (stat(pNew->name, &(pNew->info)) == -1)
    perror(pNew->name);
    pNew->flag = 1;
    pTail->pNext = pNew;
    pNew->pNext = NULL;
    pTail = pNew;
    }
    closedir(dir_ptr);
    }
    return pHead;
    }

    void do_free(File *pHead)
    {
    File *p = pHead;
    while (pHead != NULL)
    {
    p = pHead->pNext;
    free(pHead);
    pHead = p;
    }
    }
    /*具体思路:比如:当传入-name时,就要去判断改变name的状态,但是怎样*/
    /*根据传入的参数执行相应的操作*/

    void do_find(int argc, char *argv[], File *pHead)
    {
    int i=2;
    while (i < argc)
    {
    if (strcmp(argv[i], "-name") == 0)//判断输入的参数是否是-name
    {
    if (i+1 < argc)//判断后面是否还有输入
    {
    name = argv[i+1];
    change_name_flag(pHead);
    }
    else
    {
    printf("input name error! ");
    do_free(pHead);//先释放空间,然后退出
    exit(-1);
    }
    }
    else if(strcmp(argv[i], "-size") == 0) //尺寸输入的是数字,但是是作为字符被识别的,因此需要使用字符串转数字的函数(atoi)
    {
    if (i+1<argc)
    {
    change_size_flag(pHead, atoi(argv[i+1]));
    }
    else
    {
    printf("input size error! ");
    do_free(pHead);
    exit(-1);
    }
    }
    else if(strcmp(argv[i], "-type") == 0)/*下面这两处代码不规整,健壮性不够, 具体参见上面的写法*/
    {
    if (strcmp(argv[i+1], "-d") == 0)
    change_dir_flag(pHead);
    else if (strcmp(argv[i+1], "-") == 0)
    change_file_flag(pHead);
    else if (strcmp(argv[i+1], "-b") == 0)
    change_bdev_flag(pHead);
    else if (strcmp(argv[i+1], "-c") == 0)
    change_cdev_flag(pHead);
    else
    {
    }
    }
    else if (strcmp(argv[i], "-gid") == 0)/*通过id命令可以查看当前的用户号,查找时也是通过用户号进行查找*/
    {
    change_gid_flag(pHead, atoi(argv[i+1]));
    }
    else if (strcmp(argv[i], "-uid") == 0)
    {
    change_uid_flag(pHead, atoi(argv[i+1]));
    }
    else
    {}
    i+=2;
    }
    }

    void change_name_flag(File *pHead)//应该对目录中的每一项进行一个遍历
    {
    File *p = pHead->pNext;
    while (p != NULL)
    {
    if (strstr(p->name, name) == NULL && p->flag == 1)//说明在节点中没有与name相同的信息,标志设为0
    p->flag = 0;
    p = p->pNext;
    }
    }

    void change_size_flag(File * pHead, long size)//atoi(argv[i+1])的结果是把字符串转换为数字(本例中的size)
    {
    File *p = pHead->pNext;
    while (p != NULL)
    {
    if ((p->info).st_size > size && p->flag == 1)
    p->flag = 0;
    p = p->pNext;
    }
    }

    void change_dir_flag(File *pHead)
    {
    File *p = pHead->pNext;
    while (p != NULL)
    {
    if (!S_ISDIR(p->info.st_mode) && p->flag == 1)
    p->flag = 0;
    p = p->pNext;
    }
    }


    void change_file_flag(File *pHead)
    {
    File *p = pHead->pNext;
    while (p != NULL)
    {
    if (!S_ISREG(p->info.st_mode) && p->flag == 1)
    p->flag = 0;
    p = p->pNext;
    }
    }


    void change_bdev_flag(File *pHead)
    {
    File *p = pHead->pNext;
    while (p != NULL)
    {
    if (!S_ISBLK(p->info.st_mode) && p->flag == 1)
    p->flag = 0;
    p = p->pNext;
    }
    }


    void change_cdev_flag(File *pHead)
    {
    File *p = pHead->pNext;
    while (p != NULL)
    {
    if (!S_ISCHR(p->info.st_mode) && p->flag == 1)
    p->flag = 0;
    p = p->pNext;
    }
    }

    void change_gid_flag(File *pHead, long gid)
    {
    File * p = pHead->pNext;
    while (p != NULL)
    {
    if (p->info.st_gid != gid && p->flag == 1)
    p->flag = 0;
    p = p->pNext;
    }
    }

    void change_uid_flag(File * pHead, long uid)
    {
    File * p = pHead->pNext;
    while (p != NULL)
    {
    if (p->info.st_uid != uid && p->flag == 1)
    p->flag = 0;
    p = p->pNext;
    }
    }

    void print(File *pHead)//打印出所需要的信息(对节点的每一项进行一个遍历,如果状态为1,则将之打印出来)
    {
    File * p = pHead->pNext;
    while (p != NULL)
    {
    if (p->flag == 1)
    {
    printf("%s ", p->name);
    }
    p = p->pNext;
    }
    }

  • 相关阅读:
    aidl 详解
    为什么我选择用 flutter
    hunting
    Dynamic programming
    android 微信开发交流群
    hash function 字符串哈希函数
    函数也可以看成是空间的变换
    语法树
    生活中的物理随处可见
    about coroutine
  • 原文地址:https://www.cnblogs.com/zsw-1993/p/5506583.html
Copyright © 2011-2022 走看看