标题 | linux c模拟ls命令详解 |
内容 | 本篇文章是对linux中基于c模拟ls命令的实现方法进行了详细的分析介绍,需要的朋友参考下 代码如下: /* 模拟ls命令,实现参数-tariRl.有些代码重复出现,可改进 可以在该程序的基础上增加参数,该程序思路清晰,容易扩展 */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/types.h> #include<unistd.h> #include<sys/stat.h> #include<dirent.h> #include<sys/ioctl.h> #include<pwd.h> #include<grp.h> #define LL (1<<0) /*带l参数标志*/ #define IL (1<<1) /*带i参数标志*/ #define RU (1<<2) /*带R参数标志*/ #define TL (1<<16) /*带t参数标志*/ #define AL (1<<17) /*带a参数标志*/ #define RL (1<<18) /*带r参数标志*/ #define LENGTH 500 /*字符串最大长度*/ #define MAX_FILE_COUNT 500/*文件列表最大长度*/ /*函数声明*/ void error(char* error_message,int line); void display(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode); int file_list(char* path,struct stat* stalist,char (*namelist)[LENGTH],int mode); void display_simply(char (*namelist)[LENGTH],int n); void display_LL(struct stat * stalist,char (*namelist)[LENGTH],int n); void display_IL(struct stat * stalist,char (*namelist)[LENGTH],int n); void display_LL_IL(struct stat * stalist,char (*namelist)[LENGTH],int n); void display_RU(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode); void display_RU_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode); void display_RU_IL(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode); void display_RU_IL_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode); /*主函数*/ int main(int argc,char **argv) { int i,j; /*mode的前16个位用来标志那些能影响显示的参数,16位之后的位用来标志不影响输出格式的参数。这个程序只用到了0-3位,16-18位,如果要在该程序的基础上增加参数,可以用其他没有使用的位。 mode的第0位为1表示带l参数,mode的第1位为1表示带i参数,mode的第2位为1表示带R参数,mode的第16位为1表示带t参数,mode的第17位为1表示带a参数,mode的第18位为1表示带r参数*/ int mode=0; char error_message[LENGTH]={0};/*错误信息*/ char path[LENGTH]={0};/*路径*/ struct stat stalist[MAX_FILE_COUNT];/*文件详细信息数组*/ char namelist[MAX_FILE_COUNT][LENGTH];/*文件名数组*/ int flag=0;/*判断是否指定了目录*/ int count;/*文件个数*/ /*解析参数*/ for(i=1;i<argc;i++){ if(argv[i][0]=='-'){/*如果是选项参数*/ for(j=1;j<strlen(argv[i]);j++){ if(argv[i][j]=='l') mode=mode|LL; else if(argv[i][j]=='i') mode=mode|IL; else if(argv[i][j]=='R') mode=mode|RU; else if(argv[i][j]=='r') mode=mode|RL; else if(argv[i][j]=='a') mode=mode|AL; else if(argv[i][j]=='t') mode=mode|TL; else{ snprintf(error_message,LENGTH,"no option of %c",argv[i][j]); error(error_message,__LINE__); } } }else{/*参数为目录或文件*/ if(flag==1) error("can not specify more then two dir or file",__LINE__); else flag=1; if(argv[i][0]!='/'){/*相对路径*/ strcat(path,get_current_dir_name()); strcat(path,"/"); strncat(path,argv[i],strlen(argv[i])); }else/*绝对路径*/ strcpy(path,argv[i]); } } if(flag==0)/*未指定任何目录或文件,则使用默认当前目录*/ strcat(path,get_current_dir_name()); /*根据mode获取指定目录下的文件*/ count=file_list(path,stalist,namelist,mode); /*根据mode显示文件*/ display(stalist,namelist,count,mode); return 0; } /*获取文件列表*/ int file_list(char* path,struct stat* stalist,char (*namelist)[LENGTH],int mode) { int i=0,index,j,k; DIR *dir; struct dirent *ptr; char str[LENGTH]; char nametemp[LENGTH]; struct stat statemp; if(stat(path,&stalist[0])<0){ // puts(path); error("the specify file is not exist",__LINE__); } if(S_ISDIR(stalist[0].st_mode)){/*如果该路径指向的是一个目录*/ if((dir=opendir(path))==NULL){/*打开目录*/ sprintf(str,"can not open %s",path); error(str,__LINE__); } chdir(path);/*改变当前工作目录到path*/ i=0; while((ptr=readdir(dir))!=NULL){/*依次读取目录下的所有文件*/ if(ptr->d_name[0]=='.' && !(mode & AL))/*忽略隐藏文件*/ continue; /*按字母顺序插入到stalist数组及namelist数组*/ for(j=i;j>0;j--){ if(strcmp(ptr->d_name,namelist[j-1])>0) break; } for(k=i;k>j;k--){ strcpy(namelist[k],namelist[k-1]); stalist[k]=stalist[k-1]; } strcpy(namelist[j],ptr->d_name); stat(ptr->d_name,&stalist[j]); i++; if(i==MAX_FILE_COUNT) error("file count beyond MAX_FILE_COUNT",__LINE__); } closedir(dir); }else{ j=strlen(path)-1; while(j>=0 && path[j]!='/'){ j--; } if(j<0) error("path error",__LINE__); j++; k=0; while(path[j]){ namelist[0][k]=path[j]; j++; k++; } namelist[0][k]=0; return 1; } if(mode & TL){/*按文件修改时间排序*/ for(j=0;j<i;j++){ index=j; for(k=j+1;k<i;k++) if(stalist[index].st_mtime<stalist[k].st_mtime){ index=k; } statemp=stalist[j]; stalist[j]=stalist[index]; stalist[index]=statemp; strcpy(nametemp,namelist[j]); strcpy(namelist[j],namelist[index]); strcpy(namelist[index],nametemp); } } if(mode & RL){/*反序排列*/ for(j=0;j<i/2;j++){ strcpy(nametemp,namelist[j]); strcpy(namelist[j],namelist[i-j-1]); strcpy(namelist[i-j-1],nametemp); statemp=stalist[j]; stalist[j]=stalist[i-j-1]; stalist[i-j-1]=statemp; } } return i; } /*根据mode选择不同的函数进行显示*/ void display(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode) { /*使mode的高16位为0*/ int m = mode & ((1<<16)-1); switch(m){ case 0: display_simply(namelist,n); break; case 1: display_LL(stalist,namelist,n); break; case 2: display_IL(stalist,namelist,n); break; case 3: display_LL_IL(stalist,namelist,n); break; case 4: display_RU(stalist,namelist,n,mode); break; case 5: display_RU_LL(stalist,namelist,n,mode); break; case 6: display_RU_IL(stalist,namelist,n,mode); break; case 7: display_RU_IL_LL(stalist,namelist,n,mode); break; } } /*不带显示选项,简单显示文件名*/ void display_simply(char (*namelist)[LENGTH],int n) { int i,maxlength=0,cols; struct winsize ts; for(i=0;i<n;i++) if(strlen(namelist[i])>maxlength) maxlength=strlen(namelist[i]); /*获取终端的大小*/ ioctl(STDIN_FILENO,TIOCGWINSZ,&ts); cols=ts.ws_col; cols/=(maxlength+1); //lines=ts.ws_row; for(i=0;i<n;i++){ if(i!=0 && i%cols==0) puts(""); printf("%*s",-(maxlength+1),namelist[i]); } putchar('n'); } /*-l 参数,显示详细文件信息*/ void display_LL(struct stat * stalist,char (*namelist)[LENGTH],int n) { int i,mode; char* str; for(i=0;i<n;i++){ mode=stalist[i].st_mode; if(S_ISDIR(mode)) printf("d"); else printf("-"); if(mode & (1<<8)) printf("r"); else printf("-"); if(mode & (1<<7)) printf("w"); else printf("-"); if(mode & (1<<6)) printf("x"); else printf("-"); if(mode & (1<<5)) printf("r"); else printf("-"); if(mode & (1<<4)) printf("w"); else printf("-"); if(mode & (1<<3)) printf("x"); else printf("-"); if(mode & (1<<2)) printf("r"); else printf("-"); if(mode & (1<<1)) printf("w"); else printf("-"); if(mode & (1<<0)) printf("x"); else printf("-"); printf(" %-3d",stalist[i].st_nlink); printf(" %-6s",getpwuid(stalist[i].st_uid)->pw_name); printf(" %-6s",getgrgid(stalist[i].st_gid)->gr_name); printf(" %-10d",stalist[i].st_size); str=ctime(&stalist[i].st_mtime); str[strlen(str)-2]=0; printf(" %s",str); printf(" %sn",namelist[i]); } } /*-i 参数,显示文件名及节点号*/ void display_IL(struct stat* stalist,char (*namelist)[LENGTH],int n) { int i,maxlength=0,cols; struct winsize ts; for(i=0;i<n;i++) if(strlen(namelist[i])>maxlength) maxlength=strlen(namelist[i]); /*获取终端的大小*/ ioctl(STDIN_FILENO,TIOCGWINSZ,&ts); cols=ts.ws_col; cols/=(maxlength+9); //lines=ts.ws_row; for(i=0;i<n;i++){ if(i!=0 && i%cols==0) puts(""); printf("%-8d ",stalist[i].st_ino); printf("%*s",-(maxlength+1),namelist[i]); } putchar('n'); } /*-li 参数,显示详细文件信息和节点号*/ void display_LL_IL(struct stat * stalist,char (*namelist)[LENGTH],int n) { int i,mode; char* str; for(i=0;i<n;i++){ printf("%-8d ",stalist[i].st_ino); mode=stalist[i].st_mode; if(S_ISDIR(mode)) printf("d"); else printf("-"); if(mode & (1<<8)) printf("r"); else printf("-"); if(mode & (1<<7)) printf("w"); else printf("-"); if(mode & (1<<6)) printf("x"); else printf("-"); if(mode & (1<<5)) printf("r"); else printf("-"); if(mode & (1<<4)) printf("w"); else printf("-"); if(mode & (1<<3)) printf("x"); else printf("-"); if(mode & (1<<2)) printf("r"); else printf("-"); if(mode & (1<<1)) printf("w"); else printf("-"); if(mode & (1<<0)) printf("x"); else printf("-"); printf(" %-3d",stalist[i].st_nlink); printf(" %-6s",getpwuid(stalist[i].st_uid)->pw_name); printf(" %-6s",getgrgid(stalist[i].st_gid)->gr_name); printf(" %-10d",stalist[i].st_size); str=ctime(&stalist[i].st_mtime); str[strlen(str)-2]=0; printf(" %s",str); printf(" %sn",namelist[i]); } } /*-R 参数,简单显示所有文件,包括目录下面的子目录*/ void display_RU(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode) { int i,count; char path[LENGTH]={0},temp[LENGTH]={0}; struct stat sta[MAX_FILE_COUNT]; char name[MAX_FILE_COUNT][LENGTH]; puts(get_current_dir_name()); display_simply(namelist,n); putchar('n'); strcpy(path,get_current_dir_name()); for(i=0;i<n;i++){ if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0) continue; if(S_ISDIR(stalist[i].st_mode)){ strcpy(temp,path); strcat(path,"/"); strcat(path,namelist[i]); count=file_list(path,sta,name,mode); display_RU(sta,name,count,mode); strcpy(path,temp); } } } /*-Rl 参数,显示所有文件,包括目录下面的子目录的详细信息*/ void display_RU_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode) { int i,count; char path[LENGTH]={0},temp[LENGTH]={0}; struct stat sta[MAX_FILE_COUNT]; char name[MAX_FILE_COUNT][LENGTH]; puts(get_current_dir_name()); display_LL(stalist,namelist,n); putchar('n'); strcpy(path,get_current_dir_name()); for(i=0;i<n;i++){ if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0) continue; if(S_ISDIR(stalist[i].st_mode)){ strcpy(temp,path); strcat(path,"/"); strcat(path,namelist[i]); count=file_list(path,sta,name,mode); display_RU_LL(sta,name,count,mode); strcpy(path,temp); } } } /*-Ri 参数,简单显示所有文件,包括目录下的子目录,及节点号*/ void display_RU_IL(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode) { int i,count; char path[LENGTH]={0},temp[LENGTH]={0}; struct stat sta[MAX_FILE_COUNT]; char name[MAX_FILE_COUNT][LENGTH]; puts(get_current_dir_name()); display_IL(stalist,namelist,n); putchar('n'); strcpy(path,get_current_dir_name()); for(i=0;i<n;i++){ if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0) continue; if(S_ISDIR(stalist[i].st_mode)){ strcpy(temp,path); strcat(path,"/"); strcat(path,namelist[i]); count=file_list(path,sta,name,mode); display_RU_IL(sta,name,count,mode); strcpy(path,temp); } } } /*-Ril 参数,显示所有文件,包括目录下面的子目录的详细信息,及节点号*/ void display_RU_IL_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode) { int i,count; char path[LENGTH]={0},temp[LENGTH]={0}; struct stat sta[MAX_FILE_COUNT]; char name[MAX_FILE_COUNT][LENGTH]; puts(get_current_dir_name()); display_LL_IL(stalist,namelist,n); putchar('n'); strcpy(path,get_current_dir_name()); for(i=0;i<n;i++){ if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0) continue; if(S_ISDIR(stalist[i].st_mode)){ strcpy(temp,path); strcat(path,"/"); strcat(path,namelist[i]); count=file_list(path,sta,name,mode); display_RU_IL_LL(sta,name,count,mode); strcpy(path,temp); } } } //错误处理函数 void error(char* error_message,int line) { char str[5]; sprintf(str,"%d:",line); strcat(str,error_message); perror(str); exit(EXIT_FAILURE); } |
随便看 |
|
在线学习网考试资料包含高考、自考、专升本考试、人事考试、公务员考试、大学生村官考试、特岗教师招聘考试、事业单位招聘考试、企业人才招聘、银行招聘、教师招聘、农村信用社招聘、各类资格证书考试等各类考试资料。