简单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\n", 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!\n");
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!\n");
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\n", p->name);
}
p = p->pNext;
}
}
简单find命令的实现的更多相关文章
- 分布式数据库中间件–(3) Cobar对简单select命令的处理过程
友情提示:非原文链接可能会影响您的阅读体验,欢迎查看原文.(http://blog.geekcome.com) 原文地址:http://blog.geekcome.com/archives/284 在 ...
- 运维程序】简单的命令控制器(支持定时命令执行、重复定时任务命令和进程管理,开发这个小程序主要是为了方便管理服务进程)【个人github项目】
一.前言: command-controller 一个运维程序,简单的命令控制器(支持定时命令执行和重复定时命令,开发这个程序主要是为了方便管理服务进程) 本来是要用python做的,但是之前做ffm ...
- 【运维程序】简单的命令控制器(支持定时命令执行、重复定时任务命令和进程管理,开发这个小程序主要是为了方便管理服务进程)【个人github项目】
一.前言: command-controller 一个运维程序,简单的命令控制器(支持定时命令执行和重复定时命令,开发这个程序主要是为了方便管理服务进程) 本来是要用python做的,但是之前做ffm ...
- linux简单常用命令
除了yum命令,还有些简单的命令,在此记录一下,加深记忆: free -h 查询内存和交换分区. rpm -qa | grep libaio 查看当前环境是否安装某rpm软件包
- ADB简单基础命令
1.查看设备 adb devices 这个命令是查看当前连接的设备, 连接到计算机的android设备或者模拟器将会列出显示 2.安装软件 adb install adb install :这个命令将 ...
- Linux下好用的简单实用命令
1.你是否为在输入了一大串命令之后发现第一个字符打错了而苦恼?只能删除重来嘛?或者一步步左移光标? NO,一个组合键轻松搞定 Ctrl+A -----到命令行首 Ctrl+E ------到命令行末 ...
- 工作中用到的简单linux命令
1.rpm包查询.卸载.安装: rpm包查询 rpm -q 包名(不带版本号.后缀等) q----query rpm包卸载 rpm -e 包名(不带版本号.后缀等)e----erase rpm包安装 ...
- maven(02)--简单的命令操作
使用maven有什么好处呢? 这个问题留到该文的末尾进行总结>v< maven测试 在上一篇文章中介绍了如何简单的编译一个java文件,执行mvn compile命令后,你会发现在你新建的 ...
- zabbix通过简单shell命令监控elasticsearch集群状态
简单命令监控elasticsearch集群状态 原理: 使用curl命令模拟访问任意一个es节点可以反馈的集群状态,集群的状态需要为green curl -sXGET http://serverip: ...
- composer安装其实可以很简单 两行命令就解决了
最近接了一个cakephp项目,就想着用composer安装实施,因为Composer 可以方便地帮你安装项目中声明所依赖的外部工具库(libraries).之前没有接触过,相对比较陌生,但是相信ph ...
随机推荐
- 2019 金蝶java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.金蝶等公司offer,岗位是Java后端开发,因为发展原因最终选择去了金蝶,入职一年时间了,也成为了面试官,之 ...
- Django---Django的中间件
Django---Django的中间件 一丶中间件介绍 什么是中间件 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Dj ...
- 【JVM学习笔记二】垃圾收集器与内存分配策略
1. 概述 1) GC的历史比Java久远 2) GC需要完成的三件事: | 哪些内存需要回收 | 什么时候回收 | 如何回收 3) Java内存运行时区域各个部分: | Java虚拟机栈.计数器.本 ...
- FastJson实现复杂对象序列化与反序列化
原文:http://blog.csdn.net/xqhadoop/article/details/62217954 一.认识FastJson 1.优势 fastjson是目前java语言中最快的jso ...
- 设计模式之动态代理(JDK代理)
动态代理跟静态代理一个很重要的区别在于,动态代理是在内存是中的,是在代码编译期后在内存是实现的,而静态代理是我们自己编写代理类,编译后生成class文件.动态代理需要借助两个类:java.lang.r ...
- DTC配置
在A和B上配置DTC(控制面板→管理工具→组件服务),配置参数如下: 使防火墙里的3个规则enable
- JavaFX 井字棋游戏
利用JavaFX设计一个井字棋游戏,其中包括了能够与玩家对战的AI.AI的实现相比五子棋来说要简单得多,可以保证AI在后手情况下绝对不会输,具体实现如下: /* * To change this li ...
- dfs 之 下一个排列
52. 下一个排列 中文English 给定一个整数数组来表示排列,找出其之后的一个排列. Example 例1: 输入:[1] 输出:[1] 例2: 输入:[1,3,2,3] 输出:[1,3,3,2 ...
- 计算机 KB,MB,GB,TB,PB,EB 计算
ASCII码:一个英文字母(不分大小写)占一个字节的空间.一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数.换算为十进制,最小值-128,最大值127.如一个ASCII码就是一个字节 ...
- adb命令篇
前言 Android的adb提供了很多命令,功能很强大,可以为开发和调试带来很大的便利.当然本文并不是介绍各种命令的文章,而是用于记录在平时工作中需要经常使用的命令,方便平时工作时使用,所以以后 ...