简单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 ...
随机推荐
- mongoDB看这篇就够了
写在前面 hello,小伙伴们,我是 pubdreamcc ,本篇文章依旧出至于我的 GitHub仓库 node学习教程 ,如果你觉得我写的还不错,欢迎给个 star ,小伙伴们的 star 是我持续 ...
- jQuery源码二之extend的实现
extend是jQuery中一个比较核心的代码,如果有查看jQuery的源码的话,就会发现jQuery在多处调用了extend方法. 作用 对任意对象进行扩展 扩展某个实例对象 对jquery本身的实 ...
- mybatis update 返回值
mybatis sql: <update id="test" parameterType="map"> update test_0731 set n ...
- SpringBoot2.x配置Cors跨域
1 跨域的理解 跨域是指:浏览器A从服务器B获取的静态资源,包括Html.Css.Js,然后在Js中通过Ajax访问C服务器的静态资源或请求.即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源 ...
- win黑窗口命令
rd 删除 文件夹, 语法: rd [/S] [/Q] [drive:]path 参数: drive 盘符 path 文件路径 /S 递归删除文件夹( 删除前, 要确认是否进行删除) /Q 关闭 ...
- Tomcat内存溢出解决方法
Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在 ...
- 团队第四次作业——Alpha1版本发布
这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign/ 这个作业要求在哪里 https:// ...
- 算法 dfs —— 将二叉树 先序遍历 转为 链表
将二叉树拆成链表 中文English 将一棵二叉树按照前序遍历拆解成为一个 假链表.所谓的假链表是说,用二叉树的 right 指针,来表示链表中的 next 指针. Example 样例 1: 输入: ...
- 项目Beta冲刺(团队7/7)
项目Beta冲刺(团队) --7/7 作业要求: 项目Beta冲刺(团队) 1.团队信息 团队名 :男上加男 成员信息 : 队员学号 队员姓名 个人博客地址 备注 221600427 Alicesft ...
- CSS float 父元素高度自适应
<html> <head><title></title><style type="text/css">*{margin: ...