Linux C编程实战——第六章 文件操作_项目实现_自写ls命令
来源:互联网 发布:长沙seo推广 编辑:程序博客网 时间:2024/05/16 17:00
自写ls命令
根据文件的操作,参考书籍资料,编写了ls命令 目前实现了 -R -r -l -a -i -t 功能
直接上代码(已经加入了详细注释):
有不足请指教! ——开心!
/*************************************************************************> File Name: my_ls.cpp> Author:chudongfang > Mail:1149669942@qq.com > Created Time: 2016年07月19日 星期二 09时35分44秒 ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <sys/stat.h>#include <unistd.h>#include <sys/types.h>#include <linux/limits.h>#include <dirent.h>#include <grp.h>#include <pwd.h>#include <errno.h>#define PARAM_NONE 0#define PARAM_A 1#define PARAM_L 2#define PARAM_I 4#define PARAM_R 8#define PARAM_T 16#define PARAM_RR 32#define MAXROWLEN 80int g_leave_len = MAXROWLEN;int g_maxlen;/******************错误分析********************/void my_err(const char *err_string,int line){fprintf(stderr, "line:%d ", line);perror(err_string);exit(1);}/********************************************* * 功能 :输出文件信息 参数 -l * 参数1 文件信息 * 参数2 文件名 * 参数3 文件显示颜色 *********************************************/void display_attribute(struct stat buf,char * name,int filecolor){ char colorname[NAME_MAX + 30];char buf_time[32];struct passwd *psd;struct group *grp;/****************文件类型**********************/if(S_ISLNK(buf.st_mode)){printf("l");} else if(S_ISREG(buf.st_mode)){printf("-");} else if(S_ISDIR(buf.st_mode)){printf("d");} else if(S_ISCHR(buf.st_mode)){printf("c");} else if(S_ISBLK(buf.st_mode)){printf("b");} else if(S_ISFIFO(buf.st_mode)){printf("f");} else if(S_ISSOCK(buf.st_mode)){printf("s");}/********************文件权限**************************/ //拥有者权限 if(buf.st_mode & S_IRUSR) printf("r");else printf("-");if(buf.st_mode & S_IWUSR)printf("w");else printf("-");if(buf.st_mode & S_IXUSR){printf("x"); }else printf("-"); //组权限if(buf.st_mode & S_IRGRP)printf("r");else printf("-"); if(buf.st_mode & S_IWGRP)printf("w");else printf("-");if(buf.st_mode & S_IXGRP){printf("x"); }else printf("-"); //其他用户权限if(buf.st_mode & S_IROTH)printf("r");else printf("-"); if(buf.st_mode & S_IWOTH)printf("w");else printf("-");if(buf.st_mode & S_IXOTH){printf("x"); }else printf("-"); printf("\t"); //通过用户和组id得到用户的信息和其所在组的信息psd = getpwuid(buf.st_uid);grp = getgrgid(buf.st_gid);printf("%4d ",buf.st_nlink); //打印文件的硬链接数printf("%-8s",psd->pw_name); //打印用户的名字printf("%-8s", grp->gr_name); //打印用户组的名字printf("%6d", buf.st_size); //打印文件大小strcpy(buf_time,ctime(&buf.st_mtime));//把时间转换成普通表示格式buf_time[strlen(buf_time)-1]='\0'; //去掉换行符printf(" %s", buf_time);//输出时间 sprintf(colorname,"\033[%dm%s\033[0m",filecolor,name);printf(" %-s\n", colorname);}/******************************* * 功能 :输出文件名 * 参数1 文件名 * 参数2 文件显示参数 * *****************************/void display_single(char *name,int filecolor){char colorname[NAME_MAX + 30];int i,len; //剩余空间不够,就进行换行 if(g_leave_len < g_maxlen){printf("\n");g_leave_len=MAXROWLEN;} //名字的长度len = strlen(name);len = g_maxlen - len;sprintf(colorname,"\033[%dm%s\033[0m",filecolor,name);printf(" %-s", colorname);//输出若个个空格,补够一个单位 for(i=0;i<len;i++)printf(" ");printf(" "); //更新剩余空间g_leave_len -= (g_maxlen+2);}/******************************************** * 功能:输出带有i_node的文件信息 * 参数1 文件信息 * 参数2 文件名 * 参数3 显示颜色 * *****************************************/void display_st_ino(struct stat buf,char *name,int filecolor){char colorname[NAME_MAX + 30];int i,len; //剩余空间不够,就进行换行 if(g_leave_len < g_maxlen+8){printf("\n");g_leave_len=MAXROWLEN;}printf("%d ", buf.st_ino); //名字的长度len = strlen(name);len = g_maxlen - len;sprintf(colorname,"\033[%dm%s\033[0m",filecolor,name);printf(" %-s", colorname);//输出若个个空格,补够一个单位 for(i=0;i<len;i++)printf(" ");printf(" "); //更新剩余空间g_leave_len -= (g_maxlen+2+8);}/********************************************** * 功能:根据参数及路径输出单个文件信息 * 参数1 参数信息 * 参数2 单个文件路径 * ********************************************/void display(int flag,char * pathname){ int filecolor=37;int i,j;struct stat buf;//文件信息bufchar name[NAME_MAX + 1];for(i=0,j=0; i<strlen(pathname);i++){if(pathname[i] == '/'){j=0;continue;}name[j++]=pathname[i];}name[j]='\0';if(lstat(pathname,&buf) == -1){my_err("stat",__LINE__);}if(S_ISLNK(buf.st_mode)){} else if(S_ISREG(buf.st_mode)){} else if(S_ISDIR(buf.st_mode)){ filecolor=34;} else if(S_ISCHR(buf.st_mode)){ filecolor=33;} else if(S_ISBLK(buf.st_mode)){ filecolor=33;} else if(S_ISFIFO(buf.st_mode)){} else if(S_ISSOCK(buf.st_mode)){} if(filecolor == 37&& ( (buf.st_mode & S_IXUSR)|| (buf.st_mode & S_IXGRP)|| (buf.st_mode & S_IXOTH) ) ){ filecolor=32; } /********************文件权限**************************/ switch(flag){case PARAM_NONE:if(name[0]!='.'){display_single(name,filecolor);}break;case PARAM_I:if(name[0]!='.'){display_st_ino(buf,name,filecolor);}break;case PARAM_A:display_single(name,filecolor);break;case PARAM_L:if(name[0] != '.'){display_attribute(buf, name,filecolor);}break;case PARAM_A+PARAM_L:display_attribute(buf,name,filecolor);break;case PARAM_A+PARAM_I:display_st_ino(buf,name,filecolor);break;case PARAM_L+PARAM_I:if(name[0] != '.'){printf("%d ",buf.st_ino);display_attribute(buf, name,filecolor);}break;case PARAM_A+PARAM_L+PARAM_I:{printf("%d ",buf.st_ino);display_attribute(buf,name,filecolor);}break;default:break;}}/***************************************** 功能:输出目录信息* 参数1 参数信息* 参数2 目录文件路径* *************************************/void display_dir(int flag_param,char *path){DIR *dir;long t;int flag_param_temp;struct stat buf;struct dirent *ptr;int count = 0;char filename[256][PATH_MAX+1],temp[PATH_MAX+10];long filetime[256][1];flag_param_temp=flag_param;dir = opendir(path);if(dir == NULL){my_err("opendir",__LINE__);}//解析文件个数,及文件名的最长值 while((ptr = readdir(dir))!= NULL){if(g_maxlen < strlen(ptr->d_name))g_maxlen = strlen(ptr->d_name);count++;} closedir(dir);if(count>256) printf("%d :too many files under this dir",__LINE__); int i,j,len = strlen(path);dir = opendir(path); //得到该目录下的所有文件的路径 for(i=0;i < count; i++) {ptr = readdir(dir);if(ptr == NULL){my_err("opendir",__LINE__);}strncpy(filename[i],path,len);filename[i][len] = '\0';strcat(filename[i],ptr->d_name);filename[i][len+strlen(ptr->d_name)] = '\0'; }closedir(dir); //插入排序 if(flag_param & PARAM_T)//根据时间排序 { for(i=0;i<count;i++) { stat(filename[i],&buf); filetime[i][0]=buf.st_mtime; } for(i=0;i<count;i++){for(j=i;j<count;j++){if(filetime[i][0]<filetime[j][0]){t =filetime[i][0];filetime[i][0]=filetime[j][0];filetime[j][0]=t;strcpy(temp,filename[i]);strcpy(filename[i],filename[j]);strcpy(filename[j],temp);}}}flag_param -= PARAM_T; } else//根据名字排序 { for(i=0;i<count;i++){for(j=i;j<count;j++){if(strcmp(filename[i],filename[j])>0){strcpy(temp,filename[i]);strcpy(filename[i],filename[j]);strcpy(filename[j],temp);}}} } //输出文件 if(flag_param & PARAM_R)//逆序 { flag_param -= PARAM_R; if(flag_param & PARAM_RR)//递归输出{flag_param -= PARAM_RR; for (i = count-1; i >= 0; i--){stat(filename[i],&buf);if(S_ISDIR(buf.st_mode)){len=strlen(filename[i]);if(filename[i][len-1]=='.' && filename[i][len-2]=='/'||filename[i][len-1] == '.' && filename[i][len-2]=='.'&&filename[i][len-3]=='/') continue;printf("\n\n%s :\n",filename[i]);len=strlen(filename[i]);filename[i][len]='/';filename[i][len+1]='\0';display_dir(flag_param_temp,filename[i]);}elsedisplay(flag_param,filename[i]);}}else{for (i = count-1; i >= 0; i--){display(flag_param,filename[i]);}} } else { if(flag_param & PARAM_RR){flag_param -= PARAM_RR; for (i = 0; i < count; i++){stat(filename[i],&buf);if(S_ISDIR(buf.st_mode)){len=strlen(filename[i]);if(filename[i][len-1]=='.' && filename[i][len-2]=='/'||filename[i][len-1] == '.' && filename[i][len-2]=='.'&&filename[i][len-3]=='/') continue;printf("\n\n%s :\n",filename[i]);len=strlen(filename[i]);filename[i][len]='/';filename[i][len+1]='\0';display_dir(flag_param_temp,filename[i]);}elsedisplay(flag_param,filename[i]);}}else{for (i = 0; i < count; i++){display(flag_param,filename[i]);}} }if((flag_param & PARAM_L) == 0) printf("\n");}int main(int argc, char const *argv[]){int i,j,k,num;char path[PATH_MAX+1];char param[32];int flag_param = PARAM_NONE;struct stat buf;j=0;num=0; //解析其参数for(i=1; i<argc;i++){if(argv[i][0] == '-'){for(k=1;k<strlen(argv[i]);k++,j++){param[j] = argv[i][k];}num++;}} //利用位运算确定具体参数for(i=0;i<j;i++) {if(param[i] == 'a'){flag_param |=PARAM_A;//利用位运算continue; } else if(param[i] == 'l'){flag_param |= PARAM_L;continue;} else if(param[i] == 'i'){flag_param |= PARAM_I;continue;} else if(param[i] == 'r'){flag_param |= PARAM_R;continue;} else if(param[i] == 't'){flag_param |= PARAM_T;continue;}else if(param[i] == 'R'){flag_param |= PARAM_RR;continue;} else{printf("my_ls: incalid option -%c\n", param[i]);exit(1);}} param[j] = '\0'; //默认为当前路径if((num+1) == argc) {strcpy(path,"./");path[2] = '\0';display_dir(flag_param,path);return 0;} i =1;do{ if(argv[i][0] == '-') {i++;continue;} else { //得到具体路径strcpy(path, argv[i]);if(stat(path,&buf) == -1)my_err("stat",__LINE__); //判断是否为目录文件 if(S_ISDIR(buf.st_mode)){ //如果目录最后忘记了/则加上if(path[strlen(argv[i]) - 1] != '/'){path[strlen(argv[i])] = '/';path[strlen(argv[i])+1] = '\0';}else path[strlen(argv[i])] = '\0'; display_dir(flag_param,path);//按照目录输出i++;} else{ //按照文件输出display(flag_param,path);i++;}}}while (i < argc); return 0;}
0 0
- Linux C编程实战——第六章 文件操作_项目实现_自写ls命令
- Linux C编程实战——第七章 进程控制_项目实现_自写shell
- Linux C编程实战——第六章 文件操作
- Linux入门学习-文件操作_第六章
- 自写项目——实现tesseract-ocr功能_项目规划
- LinuxC编程实战学习——第六章文件操作
- 自写项目——实现tesseract-ocr功能_初步socket实现
- Linux编程——ls命令的实现
- Linux C编程第六回 - 文件操作
- Linux命令自己写 — ls
- linux命令_文件
- Linux C变成小例子——实现ls命令
- linux c实现ls命令
- Linux _文件操作
- 用c语言实现Linux命令ls操作
- 使用linux-c编程实现简单的ls命令
- linux文件和目录操作(附ls命令实现)
- linux系统open、 write、文件操作, ls命令实现
- Android Image 圆角图片与圆形图片 ImageView
- 蛇形矩阵
- 1sting hd 1865
- python组合数据类型
- 【HDU2048】数塔(简单动态规划/DP)
- Linux C编程实战——第六章 文件操作_项目实现_自写ls命令
- 用httpPost对Json发送和接收的例子
- 2016/07/20 多线程
- Xib文件的建立与显示
- Base64小记
- iOS 边缘滑动返回
- HDOJ 2089 不要62
- MinGW 下编译 libcurl
- 开发人员的网页汇总