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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 gta5老是掉线怎么办ps4 养狗身上有味道怎么办 身上有异味怎么办%3f 花钱花多了后悔怎么办 想去当兵有纹身怎么办 爸家里人欺负我妈怎么办 部队退伍登记表填错怎么办 新手程序员第一次做项目怎么办 十六岁月经量少怎么办 大姨妈第一天痛怎么办 月经第一天很疼怎么办 神器挑战任务放弃了怎么办 内蒙古森林武警改革新兵怎么办 手挨打了有点肿怎么办 征兵过程中身份证号重复怎么办 去当兵身上有纹身怎么办 武警警卫部队改革新兵怎么办 肾结石3mm很痛怎么办 剖腹产第6天肾结石痛怎么办 左肾5mm结石怎么办 肾结石手术后反复发烧怎么办 百世快递会被退回怎么办 身份证被列入黑名单了怎么办 顺丰寄方客户要求退回快递费怎么办 蛋蛋被皮筋弹肿了怎么办 人肌肉里的绦虫卵怎么办 鞋子前面踢坏了怎么办 猫割完蛋蛋流东西怎么办 北京怡瑞被骗后怎么办 玩滑板睾丸碎了怎么办 雄鸽不会踩蛋怎么办 玩滑板蛋碎了怎么办 精子在精囊满了怎么办 孩子的睾丸一大一小怎么办 肾阳虚早射该怎么办 有奶水吸不出来怎么办 苹果mac商店里没有软件怎么办 战地1安装包损坏怎么办 战地4db显示数据异常怎么办 战地1亚服没人怎么办 战地一加载太慢怎么办