自寫(xiě)ls命令
根據(jù)文件的操作,參考書(shū)籍資料,編寫(xiě)了ls命令 ? 目前實(shí)現(xiàn)了 -R ?-r ? -l ?-a ? -i ?-t 功能
直接上代碼(已經(jīng)加入了詳細(xì)注釋):
有不足請(qǐng)指教! ? ? ?——開(kāi)心!
/*************************************************************************> File Name: my_ls.cpp> Author:chudongfang > Mail:1149669942@qq.com > Created Time: 2016年07月19日 星期二 09時(shí)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;/******************錯(cuò)誤分析********************/
void my_err(const char *err_string,int line)
{fprintf(stderr, "line:%d ", line);perror(err_string);exit(1);
}/********************************************** 功能 :輸出文件信息 參數(shù) -l* 參數(shù)1 文件信息* 參數(shù)2 文件名* 參數(shù)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;
/****************文件類(lèi)型**********************/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");}/********************文件權(quán)限**************************/ //擁有者權(quán)限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("-");//組權(quán)限 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("-");//其他用戶權(quán)限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"); //通過(guò)用戶和組id得到用戶的信息和其所在組的信息psd = getpwuid(buf.st_uid);grp = getgrgid(buf.st_gid);printf("%4d ",buf.st_nlink); //打印文件的硬鏈接數(shù)printf("%-8s",psd->pw_name); //打印用戶的名字printf("%-8s", grp->gr_name); //打印用戶組的名字printf("%6d", buf.st_size); //打印文件大小strcpy(buf_time,ctime(&buf.st_mtime));//把時(shí)間轉(zhuǎn)換成普通表示格式buf_time[strlen(buf_time)-1]='\0'; //去掉換行符printf(" %s", buf_time);//輸出時(shí)間 sprintf(colorname,"\033[%dm%s\033[0m",filecolor,name);printf(" %-s\n", colorname);
}/******************************** 功能 :輸出文件名* 參數(shù)1 文件名* 參數(shù)2 文件顯示參數(shù)* *****************************/void display_single(char *name,int filecolor)
{char colorname[NAME_MAX + 30];int i,len;//剩余空間不夠,就進(jìn)行換行 if(g_leave_len < g_maxlen){printf("\n");g_leave_len=MAXROWLEN;}//名字的長(zhǎng)度len = strlen(name);len = g_maxlen - len;sprintf(colorname,"\033[%dm%s\033[0m",filecolor,name);printf(" %-s", colorname);//輸出若個(gè)個(gè)空格,補(bǔ)夠一個(gè)單位for(i=0;i<len;i++)printf(" ");printf(" ");//更新剩余空間g_leave_len -= (g_maxlen+2);
}/********************************************* 功能:輸出帶有i_node的文件信息* 參數(shù)1 文件信息* 參數(shù)2 文件名* 參數(shù)3 顯示顏色* *****************************************/
void display_st_ino(struct stat buf,char *name,int filecolor)
{char colorname[NAME_MAX + 30];int i,len;//剩余空間不夠,就進(jìn)行換行 if(g_leave_len < g_maxlen+8){printf("\n");g_leave_len=MAXROWLEN;}printf("%d ", buf.st_ino);//名字的長(zhǎng)度len = strlen(name);len = g_maxlen - len;sprintf(colorname,"\033[%dm%s\033[0m",filecolor,name);printf(" %-s", colorname);//輸出若個(gè)個(gè)空格,補(bǔ)夠一個(gè)單位for(i=0;i<len;i++)printf(" ");printf(" ");//更新剩余空間g_leave_len -= (g_maxlen+2+8);
}/*********************************************** 功能:根據(jù)參數(shù)及路徑輸出單個(gè)文件信息* 參數(shù)1 參數(shù)信息* 參數(shù)2 單個(gè)文件路徑* ********************************************/
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;}/********************文件權(quán)限**************************/ 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;}
}/****************************************
* 功能:輸出目錄信息
* 參數(shù)1 參數(shù)信息
* 參數(shù)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__);}//解析文件個(gè)數(shù),及文件名的最長(zhǎng)值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)//根據(jù)時(shí)間排序{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//根據(jù)名字排序{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;//解析其參數(shù)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++;}}//利用位運(yùn)算確定具體參數(shù)for(i=0;i<j;i++){if(param[i] == 'a'){flag_param |=PARAM_A;//利用位運(yùn)算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';//默認(rèn)為當(dāng)前路徑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;
}
總結(jié)
以上是生活随笔為你收集整理的Linux C编程实战——第六章 文件操作_项目实现_自写ls命令的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。