Unix类ls的小程序
来源:互联网 发布:json字符串base64加密 编辑:程序博客网 时间:2024/05/16 08:17
【基本功能】
(1)与 ls 命令类似,命令行参数可以有 0 到多个
0 个参数:列出当前目录下所有文件
参数为普通文件:列出文件
参数为目录:列出目录下所有文件
(2)实现自定义选项 r,a,l,h,m 以及–r 递归方式列出子目录
a 列出文件名第一个字符为圆点的普通文件(默认情况下不列出
文件名首字符为圆点的文件)
l 后跟一整数,限定文件大小的最小值(字节)
h 后跟一整数,限定文件大小的最大值(字节)
m 后跟一整数 n,限定文件的最近修改时间必须在 n 天内
– 显式地终止命令选项分析
【程序源码】
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<errno.h>#include<dirent.h>#include<sys/stat.h>char mPath[50];//用户输入的路径const int _end=5;const int _r = 0;const int _a = 1;const int _l = 2;const int _h = 3;const int _m = 4;int switch_order(int argc, char **argv);//分解参数,成功则返回0,否则返回-1int execute_order();//执行指令,成功则返回0,否则返回-1void show_info(const struct dirent *entry,struct stat st);/***********指令************** 共有6个额外的可选指令 ** -r 递归方式列出子目录* -a 列出文件名第一个字符为圆点的普通文件* -l 后跟一整数,限定文件大小的最小值(字节)* -h 后跟一整数,限定文件大小的最大值(字节)* -m 后跟一整数n,限定文件的最近修改时间必须在n天内* --显式地终止命令选项分析****************************/int mOrder[6] = { 0 };//指令默认为空long mMax_size;//最大文件尺寸long mMin_size;//最小文件尺寸time_t mDays_limit;//-m的时间限制,另外,time_t其实是long的别名time_t mCurrent_time;int main(int argc, char **argv){ //DIR *dir; if(switch_order(argc, argv)==0){//如果转换指令成功 execute_order(mPath); } // dir = opendir(argv[1]); // if (dir == NULL) { // printf("Open directory \"%s\": %s (ERROR %d)\n", // argv[1], strerror(errno), errno); // return 1; // } // printf("entry->d_ino\tentry->d_name\tentry->d_type\n" ); // while ((entry = readdir(dir)) != NULL){ // printf("%4d %s %s\n", entry->d_ino, entry->d_name,entry->d_type); // } // closedir(dir); return 0;}int switch_order(int argc, char **argv){ time(&mCurrent_time);//获取指令执行时的时间 if (argc == 1) {//目前的指令数目不足(没有参数是1,这里没有参数是不允许的) printf("the num of the order is not enough\n"); system("pause"); return 1; } int i = 0; int j = 0; while (i <= argc - 2){//参数紧跟在命令之后,目录在最后面,共有argc-1个参数,减去目录共有argc-2个 if (argv[++i][0] == '-'){//检测到是指令 switch (argv[i][1]){ case 'r': mOrder[_r] = 1; break; case 'a': mOrder[_a] = 1; break; case 'l': mOrder[_l] = 1; if ((mMin_size = atol(argv[++i])) == 0){ printf("something wrong with \"-l\" in the order\n"); system("pause"); return 1; } break; case 'h': mOrder[_h] = 1; if ((mMax_size = atol(argv[++i])) == 0){ printf("something wrong with \"-h\" in the order\n"); system("pause"); return 1; } break; case 'm': mOrder[_m] = 1; if ((mDays_limit = atol(argv[++i])) == 0){ printf("something wrong with \"-m\" in the order\n"); system("pause"); return 1; } break; case '-': mOrder[_end] = 1; break; } } else{ //不是-开头则认为是路径 strcpy(mPath, argv[i]); } } printf("path is %s\n",mPath); return 0;//linux return 0表示运行成功}/********************************执行指令,如果成功则返回0,失败则返回1********************************/int execute_order(const char *path){//传入一个path int ret; struct stat st; struct dirent *entry;//目录里文件的读取指针 char current_path[50]; ret = stat(path, &st); DIR *dir; if(ret==0){ if(S_ISDIR(st.st_mode)){ //如果是目录 dir=opendir(path); if(dir==NULL){ //读取失败 printf("Open dir \"%s\" :%s,ERROR(%d)\n",path,strerror(errno),errno); return 1; } while((entry=readdir(dir))!=NULL){ //这里需要特别注意一下 //entry中会出现当前文件夹和上层文件夹的目录索引 很明显这并不是我们想要的 //所以这里需要特别注意一些 char* current_dir_string="."; char* parent_dir_string=".."; if(strcmp(entry->d_name,current_dir_string)!=0&&strcmp(entry->d_name,parent_dir_string)!=0){//如果并不是当前目录 //获取当前文件夹下面的各个文件的stat strcpy(current_path,path); strcat(current_path,"/"); strcat(current_path,entry->d_name); ret=stat(current_path,&st); // printf("%s\n",current_path); if(ret==0){ //如果成功获取了stat show_info(entry,st); if(S_ISDIR(st.st_mode)){//如果当前文件是文件夹 if(mOrder[_r]&&!mOrder[_end]){//如果是递归 execute_order(current_path); } } } else{//失败则返回原因 printf("Read file \"%s\" :%s,ERROR(%d)\n",path,strerror(errno),errno); } } } closedir(dir); } else{//如果这只是一个文件罢了 printf("%d\t%d\n",st.st_size,st.st_mtime); } } return 0;}/*******************用来对内容进行过滤*******************/void show_info(const struct dirent* entry,struct stat st){ //对文件进行选择性过滤 // int count; // for(count=0;count<6;count++){ // printf("%d : %d\n",count,mOrder[count]); // } // printf("%d %d\n",_end,mOrder[_end]); if(mOrder[_end]==0){ if(mOrder[_a]||entry->d_name[0]!='.'){//默认的情况下以‘.’开头的文件并不会显示出来 if(!mOrder[_l]||st.st_size>mMin_size){ if(!mOrder[_h]||st.st_size<mMax_size){ if(!mOrder[_m]||((mCurrent_time-st.st_mtime)/86400)<mDays_limit){ printf("%d\t%d\t%s\n",st.st_size,st.st_mtime,entry->d_name); } } } } } else{ printf("%d\t%d\t%s\n",st.st_size,st.st_mtime,entry->d_name); }}
【运行效果】
<1>基本指令(路径)
<2>进行最大文件过滤
<3>进行最小文件过滤
<4>日期过滤
<5>递归显示所有文件
<6>单个文件测试
<7>综合测试
<8>终止指令测试
【存在的问题】
程序的功能虽然基本实现了,但是程序编写时一些疑惑没有解决。比如,使用了全局变量来保存用户指令,偶尔在编译之后会出现异常。
Const int _i=5在之前的时候命名是const int _end=5。但是非常蹊跷的是,在main函数的开头处打印这个数值,显示的是1!这修改了常量的名称之后又恢复了正常。
(此处怀疑是头文件中的全局变量出现了_end这个常量?但是在我后来的修改中这一问题又消失了)
还有,在show_info()函数中,如果想转换时间戳为字符串格式时。printf(“%d\t%s\t%s\n”,st.st_size,ctime(st.st_mtime),entry->d_name);
在编译过程中不会出错,但是很蹊跷得在运行时显示segment fault。这本是风马牛不相及的错误。
Gcc编译器的调试对我依然很难。第一个问题可能很难再现了。第二个问题希望有人可以和我探讨一下514201942@qq.com
- Unix类ls的小程序
- UVA400-Unix的ls命令
- Unix ls
- Unix Socket 小程序
- UVa 400 Unix的ls命令
- 2.Unix高级编程-----ls的实现
- UVA - 400 Unix ls qsort的用法
- Unix - ls命令的简要实现
- unix/linux ls命令的实现
- unix ls命令的一个简单实现
- 自己写的小ls
- 编写自己的ls程序
- ls小程序,使用到文件信息和权限等的获取
- UVa 400 - Unix ls
- POJ 1589 Unix ls
- HOJ 1011 Unix ls
- poj1589 Unix ls
- POJ 1589 Unix ls
- sass结合compass使用(图文)
- 自定义 Android 对话框 (AlertDialog) 的样式
- [CS@Nets][编译原理]一个栈式计算机的加法语言编译器
- 南京揭秘响一声电话吸费 声讯电话平台
- 15年省赛和东北区域赛总结
- Unix类ls的小程序
- R软件学习笔记—Legend
- CentOS 编译安装 PyCrypto
- 威海高收费电话加盟 2014好项目 电话群呼器
- 时间
- ruby元编程读后感
- 轮廓处理之一
- 线程中sleep()方法和yeild()方法的区别
- Oracle创建用户、表空间、导入导出、...命令