简单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后端开发,因为发展原因最终选择去了拉卡拉,入职一年时间了,也成为了面试官 ...
- kylin安装过程问题排查
问题:日志报错:/usr/local/apps/kylin/tomcat/conf/.keystore (没有那个文件或目录) 解决:在kylin内置tomcat的server.xml中里边有个对ht ...
- 【转载】C#中ArrayList集合类使用RemoveAt方法移除指定索引的元素
ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,在Array ...
- Qt Graphics-View的打印功能实现
本文来研究一下Qt Graphics-View的打印功能实现. 在Qt的官方文档中介绍了Graphics-View的打印相关内容. Qt中对打印的支持是有一个独立的printsupport模块来完成的 ...
- 关于连接不上SVN的部分解决方案——No repository found in svn localhost
今天如往常一样做事,期间发现一个问题,于是就打算将文件与 svn 上的文件进行对比,可谁成想 Eclipse 突然弹框报错,然后我到SVN资源库中直接刷新打开 svn 的地址,又弹框报错:文件夹不存在 ...
- idea中导入Maven项目,但是没有Maven Dependencies,且没有pom
1. 可以复制其他项目的类似的pom.xml文件复制到当前项目下 2. 导入此项目为maven项目 3. 配置相应的maven环境 4. 如果此时的Application.class中的main方法没 ...
- web模拟终端 --使用shellinabox
关于shellinabox ShellInABox实现了一个Web服务器,可以将任意命令行工具导出到基于Web的终端仿真器.任何支持JavaScript和CSS的Web浏览器都可以访问此模拟器,并且不 ...
- freebsd缓存包与仓库版本不一致
问题描述: pkg install -y lrzsz pkg: cached package lrzsz-0.12.20_4: size mismatch, cannot continue 问题解决: ...
- Linux centos关机和重启命令
Linux centos重启命令: 1.reboot 普通重启 2.shutdown -r now 立刻重启(root用户使用) 3.shutdown -r 10 过10分钟自动重启(root用户 ...
- python调用C语言接口
python调用C语言接口 注:本文所有示例介绍基于linux平台 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题 ...