北京邮电大学Unix编程环境课程第一次实验报告ls命令.docx
- 文档编号:30228305
- 上传时间:2023-08-07
- 格式:DOCX
- 页数:17
- 大小:501.92KB
北京邮电大学Unix编程环境课程第一次实验报告ls命令.docx
《北京邮电大学Unix编程环境课程第一次实验报告ls命令.docx》由会员分享,可在线阅读,更多相关《北京邮电大学Unix编程环境课程第一次实验报告ls命令.docx(17页珍藏版)》请在冰豆网上搜索。
北京邮电大学Unix编程环境课程第一次实验报告ls命令
实验报告
实验名:
Unix编程第一次实验
课程名:
Unix编程环境
姓名:
学号:
班级:
实验目的:
练习vi,使用UNIX的系统调用和库函数,体会UNIX文件通配符的处理方式以及命令对选项的处理方式。
实验要求:
编程实现程序list.c,列表普通磁盘文件(不考虑目录和设备文件等),列出文件名和文件大小。
与ls命令类似,命令行参数可以有0到多个
Ø0个参数:
列出当前目录下所有文件
Ø参数为普通文件:
列出文件
Ø参数为目录:
列出目录下所有文件
实现自定义选项r,a,l,h,m以及--
Ør递归方式列出子目录
Øa列出文件名第一个字符为圆点的普通文件(默认情况下不列出文件名首字符为圆点的文件)
Øl后跟一整数,限定文件大小的最小值(字节)
Øh后跟一整数,限定文件大小的最大值(字节)
Øm后跟一整数n,限定文件的最近修改时间必须在n天内
Ø显式地终止命令选项
程序说明:
1)命令选项的存储:
structoptions
{
IntaFlag,
rFlag,lFlag,hFlag,mFlag;
longlPara,hPara;
intmPara;
};
采用structoptions结构存储命令的选项,flag代表有无此选项,例如aFlag为1就表示有“-a”选项,aFlag为0则表示没有“-a”选项。
lPara、hPara和mPara用来存储”-l”、”-h”、”-m”选项所带的参数。
2)命令的读取:
structpath
{
char*path;
structpath*next;
};
采用函数getCommend读取命令,声明一个opEnd变量用来指示选项的输入是否结束。
opEnd初始为0,代表选项的输入没有结束,当遇到“--“之后,opEnd置为1,代表选项输入结束。
在opEnd为0的时候,命令中以”-“开头的,都认为是一个选项,在opEnd为1的时候,命令中以”-“开头的则不作为选项而作为命令的参数。
在识别选项的同时,也要读入命令的参数,命令的参数也就是文件地址,存储在结构structpath所组成的链表当中。
在读完命令之后,需要判断一下链表是否为空,如果链表是空的则代表命令中没有参数,这是需要程序自动得把当前目录即”./“加入链表当中。
3)选项的判断:
intjudje(structoptionsoption,structstatinfo,char*fileName)
采用函数judje函数判断一个文件是否满足选项的要求,如果满足要求返回1,否则返回0。
4)选项的参数的获取:
intgetPara(char*option)
采用函数getPara获取选项所带的参数,如果参数合法则把参数转化为int并返回,如果参数不合法,比如参数中字母或符号等则返回-1;
5)打印:
voidlistFiles(char*path,structoptionsoption)
采用函数listFiles打印文件,当需要递归时,把当前打印的目录和需要递归的文件目录合并在一起传入listFiles中,进行递归。
实验结果:
1)输入命令:
./list不加选项和参数
2)输入命令:
./list–a打印文件名”.”开头的文件名及大小
3)输入命令:
./list–l4000输出大小在4000自己以上的文件名及大小
4)输入命令:
./list–h5000输出大小在5000字节一下的文件名及大小
5)输入命令:
./list–m2打印两天之内修改过的文件名及大小
6)输入命令:
./list–r|more循环打印文件名及大小
7)输入命令:
./list–r---a循环打印文件名是-a的文件夹
8)输入命令:
./listtest*(相当于./listtesttest2)
Test:
Test2:
9)输入命令:
./listlist.c打印list.c文件
10)输入命令:
./list–l3000–h5000–r–a--/home/andy|more(复杂命令)
实验总结:
在打印过程中需要考虑一下集中特殊情况:
1)命令中没有参数
2)输入的路径本身就是一个文件
3)目录中“.”文件和”..”文件的问题。
对于第一种情况:
假如没有考虑到这个情况会导致没有任何输出的问题,而这个情况下是应该打印当前目录的。
在编程中可以判断一下命令是否带有参数,如果没有参数就把当前目录当作参数传给程序。
对于第二种情况:
假如不考虑这个问题,会导致直接显示无法打开文件的情况。
编程中可以首先判断一下,输入的参数是否是一个文件来解决。
如果是一个文件就直接打印它的文件名和大小。
对于第三种情况:
假如不考虑这个问题,会导致无限递归的产生。
因为”.“文件开打后回到上层目录,打开这个目录发现里面还是有一个”.“文件,在编写”-r“选项是导致无限递归。
编程时应该额外处理”.“文件和”..”文件,在递归之前应该判断需要递归的目录是否是一个”.“文件或”..”文件,如果是,则不应该递归,如果不是,则可以递归。
实验代码:
#include
#include
#include
#include
#include
#include
#include
structpath
{
char*path;
structpath*next;
};
structoptions
{
intaFlag,rFlag,lFlag,hFlag,mFlag;
longlPara,hPara;
intmPara;
};
intjudje(structoptionsoption,structstatinfo,char*fileName)
{
longcurrentTime=(long)time(NULL);
if(option.aFlag==0&&fileName[0]=='.')
return0;
if(option.lFlag==1&&(long)info.st_size return0; if(option.hFlag==1&&(long)info.st_size>option.hPara) return0; if(option.mFlag==1&&(currentTime-(long)info.st_mtime)/86400>=option.mPara) return0; return1; } /* *usetheoptiontodeterminewhetherafileshouldbeprinted */ voidlistFiles(char*path,structoptionsoption) { DIR*dir; structdirent*files; //structfile*file; intflag;//canbeprint? structstatinfoTmp; if(stat(path,&infoTmp)! =-1&&! S_ISDIR(infoTmp.st_mode)){ printf("%-50s%ld\n",path,(long)infoTmp.st_size); return; } elseif(stat(path,&infoTmp)==-1){ fprintf(stderr,"cannotreadthestatusof%s\n",path); return; } if((dir=opendir(path))==NULL){ fprintf(stderr,"cannotopen%s\n",path); } else{ while((files=readdir(dir))! =NULL){ flag=1; structstatinfo; chartmp[200]; strcpy(tmp,path); strcat(tmp,"/"); strcat(tmp,files->d_name); if(stat(tmp,&info)==-1) fprintf(stderr,"cannotreadthestatusof%s\n",files->d_name); else{ flag=judje(option,info,files->d_name); if(flag==1){ printf("%-50s%ld\n",files->d_name,(long)info.st_size); } if(option.rFlag==1&&S_ISDIR(info.st_mode)&&flag==1){//ifit'sadirand-rexists if(strcmp(files->d_name,".")! =0&&strcmp(files->d_name,"..")! =0) listFiles(tmp,option); } } } closedir(dir); } } /* *gettheparameterafteranoption */ intgetPara(char*option) { inti=0; inttmp=0; for(;option[i]! ='\0';i++){ if(option[i]>='0'&&option[i]<='9') tmp=tmp*10+option[i]-'0'; else return-1; } returntmp; } intgetCommend(intargc,char**args) { inti;//-r-a-l-h-m-- intopEnd=0; char*tmp; structoptionsop; structpath*pathHead=NULL,*currentPtr; op.lFlag=0; op.hFlag=0; op.aFlag=0; op.mFlag=0; op.rFlag=0; /* *dealwiththecommensfindtheoptionsandfilepathes */ for(i=1;i<=argc-1;i++){ if(args[i][0]=='-'&&opEnd==0){//it'sanoption if(args[i][2]! ='\0'){ fprintf(stderr,"ls: invalidoption\n");//thisoptioniswrong return0; } switch(args[i][1]){ case'a': op.aFlag=1; break; case'r': op.rFlag=1; break; case'l': op.lFlag=1; op.lPara=getPara(args[++i]); if(op.lPara==-1){ fprintf(stderr,"ls: invalidoption\n");//wronginput return0; } break; case'h': op.hFlag=1; op.hPara=getPara(args[++i]); if(op.hPara==-1){ fprintf(stderr,"ls: invalidoption\n"); return0; } break; case'm': op.mFlag=1; op.mPara=getPara(args[++i]); if(op.mPara==-1){ fprintf(stderr,"ls: invalidoption\n"); return0; } break; case'-': opEnd=1; break; } } else{ structpath*newPtr=(structpath*)malloc(sizeof(structpath)); newPtr->path=args[i]; newPtr->next=NULL; if(pathHead==NULL) pathHead=newPtr; else currentPtr->next=newPtr; currentPtr=newPtr; } } /* *dealwitheverypathinthecommend */ if(pathHead) while(pathHead! =NULL){ printf("%s: \n",pathHead->path); listFiles(pathHead->path,op); pathHead=pathHead->next; } else{ pathHead=(structpath*)malloc(sizeof(structpath)); pathHead->path="./"; pathHead->next=NULL; listFiles(pathHead->path,op); } return1; } voidmain(intargc,char**args) { getCommend(argc,args); return; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 北京邮电 大学 Unix 编程 环境 课程 第一次 实验 报告 ls 命令
![提示](https://static.bdocx.com/images/bang_tan.gif)