下载
加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 c语言下实现ls命令

c语言下实现ls命令.doc

c语言下实现ls命令

陈松茂
2019-06-14 0人阅读 举报 0 0 暂无简介

简介:本文档为《c语言下实现ls命令doc》,可适用于IT/计算机领域

Linux下实现ls命令(仅适用于lsapathnamelslpathnamelspathname)ls命令就是list的缩写,缺省下ls用来打印出当前目录的清单,如果ls指定其他目录,那么就会显示指定目录里的文件及文件夹清单。通过ls命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录、文件夹、文件权限),查看目录信息等等,ls命令在日常的linux操作中用的很多a选项:表示显示该目录下的所有文件,包括隐藏文件。l选项:表示显示文件的详细信息,包括访问权限,文件大小……例如:ls–als–l)主要构造的函数voiderror(constchar*errstring,intline)错误处理函数,打印错误所在行数和错误信息voidDemonstrateattribute(structstatbuf,char*name)获得文件属性并打印voidDemonstratesingle(char*name)输出文件名,命令没有l选项。输出文件名要保持上下对齐voidDemonstrate(intflag,char*pathname)根据命令行参数和文件路径名来显示目标文件voidDemonstratedir(intflagparameter,char*path)为显示某个目录下的文件做准备)函数流程()获取该目录下文件的总数和最长文件名()若获该目录下所有文件的文件名,存放于变量filenames中()使用冒泡法对文件名按字母顺序存储于filenames中()调用Demonstrate()函数来显示每个文件信息)程序中主要的结构体:参数structstat*buf是一个保存文件状态信息的结构体A):structstat{devstdev文件设备号inotstino文件的inodemodetstmode文件类型和存储权限nlinktstnlink连到该文件的硬链接数目。uidtstuid文件所有者的用户idgidtstgid文件所有者的组iddevtstrdev若此文件为设备文件,则为其设备编号offtstsize文件大小blksizetstblksize文件系统的IO缓冲区大小blkcnttstblocks占用文件区块的个数timetstatime文件最近一次被访问的时间文件最后一次被修改的时间timetstctime文件最近一次被更改的时间}其中,对于stmode包含的文件类型信息,POSIX标准定义了一系列的宏:SISLNK(stmode)判断是否为符号链接SISREG(stmode)判断是否为一般文件SISDIR(stmode)判断是否为目录文件SISCHR(stmode)判断是否为字符设备文件SIBLK(stmode)判断是否为块设备文件SISFIFO(stmode)判断是否为先进先出FIFOSISFOCK(stmode)判断是否为socketB):structpasswd*psd从该结构体中获取文件所有者的用户名C):structgroup*grp从该结构体中获取文件所有者所属组的组名)心得体会本次课程设计我写的是Linux下的ls命令,通过这次课程设计,不仅使我对ls命令有了更深一层的认识,还认识到了系统提供的命令实现的途径和方法。之前总是使用系统命令,如今自己编程实现了一些命令,每次使用系统提供的命令和调用自己编写的命令感觉大不相同。)具体解析与详细代码:#include<stdioh>#include<stdlibh>#include<stringh>#include<timeh>#include<sysstath>#include<unistdh>#include<systypesh>#include<linuxlimitsh>#include<direnth>#include<grph>#include<pwdh>#include<errnoh>#definePARAMETERNONE无参数#definePARAMETERAa:显示所有文件#definePARAMETERLl:一行显示一个文件的详细信息#defineMAXROWLEN一行显示的最多字符数intgleavelen=MAXROWLEN一行剩余长度,用于输出对齐intgmaxlen存放某目录下最长文件名的长度voiderror(constchar*errstring,intline)错误处理函数,打印错误所在行数和错误信息voidDemonstrateattribute(structstatbuf,char*name)获取文件属性并打印voidDemonstratesingle(char*name)输出文件名,命令没有l选项,则输出文件名时要保持上下文对齐voidDemonstrate(intflag,char*pathname)根据命令行参数和文件路径名显示目标文件voidDemonstratedir(intflagparameter,char*path)为显示某个目录下的文件做准备intmain(intargc,char**argv){inti,j,k,numcharpathPATHMAX文件路径名charparameter保存命令行参数,目标文件名和目录名不在此列intflagparameter=PARAMETERNONE用来标志参数种类,即是否有l和a选项structstatbuf*首先对命令行参数进行解析,即提取命令行参数中‘’后的选项。用户的输入有多样性,如lslalsla。我们用两层循环类来解析参数,外层循环对argv数组中的元素依次进行内层循环的解析,二层循环对以‘’为首的字符串进行选项提取,并把每个选项存于parameter数组当中,用num记下‘’的数目,以备后用。而命令行参数中的总选项数目则用j计数。*j=,num=for(i=i<argci){if(argvi==''){for(k=k<strlen(argvi)k){parameterj=argvik获取后面的参数保存到数组parameter中j}num保存""的个数}}*检查刚刚提取的选项是否合法。并且用或运算记录参数,以备后用。最后为选项数组的末尾元素赋‘’。*checktheargumentbecauseofonlysupportingaanglfor(i=i<ji){if(parameteri=='a'){flagparameter=PARAMETERAcontinue}elseif(parameteri=='l'){flagparameter=PARAMETERLcontinue}elseprintf("myls:invalidoptioncn",parameteri)exit()}}parameterj=''*由上面所知num记录的是参数中‘’的数量,因此如果num==argc,那说明用户所输入的命令行参数不包含目录或文件名。只是显示当前目录下的文件。因为这是我们必须自动将path赋值为当前目录。为了使其称为一个字符串,必须在末尾加‘’。然后进入Demonstratedir函数*printtheinformationofcurrentdirectoryifthecommandwithoutthenameoftargetfileandcurrentdirectoryif((num)==argc){strcpy(path,"")""当前目录path=''Demonstratedir(flagparameter,path)return}*如果命令行参数包含目录或者文件名,那么我们要检查其合法性(参数中的目录或者文件是否存在)。这里我们利用stat族函数来获取文件的属性,实现上述功能。stat族函数通常有两个参数:文件路径文件描述符,structstat*buf类型的结构体。如果操作成功,那么buf将保存文件的属性。若合法,利用宏SISDIR(bufstmode),判断此文件是否为目录文件。若为目录文件则进入Demonstratedir函数,否则进入Demonstrate函数。通常情况,Demonstratedir函数是获取path目录下所有文件的完整路径名,在使每个文件执行Demonstrate函数。因此如果参数中是指定的文件名,则可绕过Demonstratedir函数,直接进入Demonstrate函数。*i=do{***如果不是目标文件名或目录,解析下一个命令行参数*if(argvi==''){icontinue}else{strcpy(path,argvi)***如果目标文件或目录不存在,报错并退出程序*if(stat(path,buf)==){error("stat",LINE)}if(SISDIR(bufstmode))argvi是一个目录如果目录的最后一个字符不是'',就加上''{if(pathstrlen(argvi)!=''){pathstrlen(argvi)=''pathstrlen(argvi)=''}else{pathstrlen(argvi)=''}Demonstratedir(flagparameter,path)i}elseargvi是一个文件{Demonstrate(flagparameter,path)i}}}while(i<argc)return}***错误处理函数,打印出错误所在行的行数和错误信息*voiderror(constchar*errstring,intline){fprintf(stderr,"line:d",line)perror(errstring)exit()}***获取文件属性并打印*voidDemonstrateattribute(structstatbuf,char*name){charbuftime存放时间structpasswd*psd从该结构体中获取文件所有者的用户名structgroup*grp从该结构体中获取文件所有者所属组的组名***获取并打印文件类型*stmode:文件内容和存取权限if(SISLNK(bufstmode))判断是否为符号链接{printf("l")}elseif(SISREG(bufstmode))判断是否为文件{printf("")}elseif(SISDIR(bufstmode))判断是否为目录{printf("d")}elseif(SISCHR(bufstmode))判断是否为字符设备文件{printf("c")}elseif(SISBLK(bufstmode))判断是否为块设备文件{printf("b")}elseif(SISFIFO(bufstmode))判断是否为先进先出的FIFO{printf("f")}elseif(SISSOCK(bufstmode))判断是否为socket{printf("s")}***获取并打印文件所有者的权限*if(bufstmodeSIRUSR){printf("r")}else{printf("")}if(bufstmodeSIWUSR){printf("w")}else{printf("")}if(bufstmodeSIXUSR){printf("x")}else{printf("")}***获取并打印与文件所有者同组的用户对该文件的操作权限*if(bufstmodeSIRGRP){printf("r")}else{printf("")}if(bufstmodeSIWGRP){printf("w")在线学习网}else{printf("")}if(bufstmodeSIXGRP){printf("x")}else{printf("")}***获取并打印其它用户的对该文件的操作权限if(bufstmodeSIROTH){printf("r")}else{printf("")}if(bufstmodeSIWOTH){printf("w")}else{printf("")}if(bufstmodeSIXOTH){printf("x")}else{printf("")}printf("")***根据uid与gid获取文件所有者的用户名与组名*psd=getpwuid(bufstuid)grp=getgrgid(bufstgid)printf("d",bufstnlink)打印文件的链接数(该文件硬链接数目)printf("s",psd>pwname)打印文件拥有者printf("s",grp>grname)打印文件所属用户组printf("d",(int)bufstsize)打印文件的大小strcpy(buftime,ctime(bufstmtime))buftimestrlen(buftime)=''去掉换行符printf("s",buftime)打印文件的时间信息}*在没有使用l选项时,打印一个文件名,打印时上下行之间进行对齐*voidDemonstratesingle(char*name)inti,len***如果本行不足以打印一个文件名则换行*if(gleavelen<gmaxlen){printf("n")gleavelen=MAXROWLEN}len=strlen(name)len=gmaxlenlenprintf("s",name)for(i=i<leni){printf("")}printf("")***下面的指示空两格*gleavelen=(gmaxlen)}**根据命令行参数和完整路径名显示目标文件*参数flag:命令行参数*参数pathname:包含了文件名的路径名*voidDemonstrate(intflag,char*pathname){inti,jstructstatbufcharnameNAMEMAX***从路径中解析出文件名**for(i=,j=i<strlen(pathname)i){if(pathnamei==''){j=continue}namej=pathnamei}namej=''**用lstat而不是stat以方便解析链接文件*if(lstat(pathname,buf)==)lstat返回的是符号链接文件文件本身的状态信息{error("stat",LINE)}switch(flag){casePARAMETERNONE:没有l和a选项if(name!=''){Demonstratesingle(name)}breakcasePARAMETERA:a:显示包括隐藏文件在内的所有文件Demonstratesingle(name)breakcasePARAMETERL:l:每个文件单独占一行,显示文件的详细属性信息if(name!=''){Demonstrateattribute(buf,name)printf("sn",name)}breakcasePARAMETERAPARAMETERL:同时有a和l选项的情况Demonstrateattribute(buf,name)printf("sn",name)breakdefault:break}}*为显示目录下的文件做准备*voidDemonstratedir(intflagparameter,char*path){DIR*dirstructdirent*ptrintcount=charfilenamesPATHMAX,tempPATHMAX获取该目录下文件总数和最长的文件名dir=opendir(path)if(dir==){error("opendir",LINE)while((ptr=readdir(dir))!=){if(gmaxlen<strlen(ptr>dname))gmaxlen=strlen(ptr>dname)count}closedir(dir)if(count>)error("toomanyfilesunderthisdir",LINE)inti,j,len=strlen(path)获取该目录下所有的文件名dir=opendir(path)for(i=i<counti){ptr=readdir(dir)if(ptr==){error("readdir",LINE)}strncpy(filenamesi,path,len)filenames存放目录下的所有文件名filenamesilen=''strcat(filenamesi,ptr>dname)filenamesilenstrlen(ptr>dname)=''}使用冒泡法对文件名进行排序,排序后文件名按字母顺序存储于filenamesfor(i=i<counti)for(j=j<countij){if(strcmp(filenamesj,filenamesj)>){strcpy(temp,filenamesj)tempstrlen(filenamesj)=''strcpy(filenamesj,filenamesj)filenamesjstrlen(filenamesj)=''strcpy(filenamesj,temp)filenamesjstrlen(temp)=''}}for(i=i<counti)Demonstrate(flagparameter,filenamesi)closedir(dir)如果命令行中没有l选项,打印一个换行符if((flagparameterPARAMETERL)==)printf("n")}

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/28

c语言下实现ls命令

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利