在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
主要用到的函数可以参考头文件,仅仅支持ls -l这功能,扩展就交给大家了0.0 相关测试图片:
编译 gcc -std=c99 ls_l.c -o ls 运行 ./ls -l ( 请勿在文件结构复杂的目录下执行,程序会挂的!) 话不多说,直接上码 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/stat.h> 5 #include <sys/types.h> 6 #include <string.h> 7 #include <time.h> 8 #include <pwd.h> 9 #include <grp.h> 10 #include <time.h> 11 #include <dirent.h> 12 13 #define MAX_FILE_NUM 200 14 15 16 //可能还有一些小问题没有解决,功能基本已经实现,如有建议,望大佬赐教 17 18 typedef struct LS 19 { 20 char mode[15]; // 文件的模式 21 int dir_num; // 是否目录或目录中包含目录的数量 22 char user[20]; // 文件的用户名 23 char group[20]; // 文件的组名 24 long size; // 文件的字节数 25 char time[30]; // 文件的最后修改时间 26 char year[5]; // 拓展用,年份 27 char mon[5]; // 月份 28 char hour[5]; // 时 29 char min[5]; // 分 30 int st_mode; // 文件类型和权限 31 char name[20]; // 文件名 32 }LS; 33 34 // 获取文件的模式 35 char* file_mode(mode_t m,char* str) 36 { 37 if(S_ISREG(m)) 38 str[0] = '-'; 39 else if(S_ISDIR(m)) 40 str[0] = 'd'; 41 else if(S_ISCHR(m)) 42 str[0] = 'c'; 43 else if(S_ISBLK(m)) 44 str[0] = 'b'; 45 else if(S_ISFIFO(m)) 46 str[0] = 'q'; 47 else if(S_ISLNK(m)) 48 str[0] = 'l'; 49 // else if(S_ISSOCK(m)) 50 // str[0] = 's'; 51 else 52 str[0] = '?'; 53 54 str[1] = '\0'; 55 56 strcat(str,S_IRUSR&m?"r":"-"); 57 strcat(str,S_IWUSR&m?"w":"-"); 58 strcat(str,S_IXUSR&m?"x":"-"); 59 60 strcat(str,S_IRGRP&m?"r":"-"); 61 strcat(str,S_IWGRP&m?"w":"-"); 62 strcat(str,S_IXGRP&m?"x":"-"); 63 64 strcat(str,S_IROTH&m?"r":"-"); 65 strcat(str,S_IWOTH&m?"w":"-"); 66 strcat(str,S_IXOTH&m?"x":"-"); 67 68 return str; 69 } 70 71 // 获取目录的数量 72 int dir_count(char* path) 73 { 74 DIR *dir; 75 dir = opendir(path); 76 struct dirent *dirent; 77 int count = 0; 78 while((dirent = readdir(dir)) != NULL) 79 { 80 if(dirent->d_type == 4) 81 count++; 82 } 83 closedir(dir); 84 return count; 85 } 86 87 // 是否是目录或目录下有目录 88 int is_dir(struct dirent *dirent) 89 { 90 char* a = dirent->d_name; 91 if(dirent->d_type == 8) 92 return 1; 93 if(dirent->d_type == 4) 94 { 95 if(dir_count(a) == 0) 96 return 2; 97 else 98 return dir_count(a); 99 } 100 } 101 102 // 获取用户名 103 char* file_user(uid_t st_uid,char* str) 104 { 105 struct passwd *user; 106 user = getpwuid(st_uid); 107 sprintf(str,"%s",user->pw_name); 108 return str; 109 } 110 111 // 获取组名 112 char* file_group(uid_t st_uid,char* str) 113 { 114 struct passwd *user; 115 user = getpwuid(st_uid); 116 struct group *grp; 117 grp = getgrgid(user->pw_gid); 118 sprintf(str,"%s",grp->gr_name); 119 return str; 120 } 121 122 // 获取文件大小 123 off_t file_size(struct stat buf) 124 { 125 off_t size = buf.st_size; 126 return size; 127 } 128 129 // 获取最后修改时间 130 char* file_time(time_t mt,char* str) 131 { 132 struct tm* t = localtime(&mt); 133 sprintf(str,"%d月 %02d %02d:%02d",t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min); 134 return str; 135 } 136 137 // 获取文件的数量 138 int file_count(char* path) 139 { 140 DIR *dir; 141 dir = opendir(path); 142 struct dirent *dirent; 143 int count = 0; 144 while((dirent = readdir(dir)) != NULL) 145 { 146 count++; 147 } 148 closedir(dir); 149 return count; 150 } 151 152 // 交换 153 void equal(LS *a,LS *b) 154 { 155 strcpy(a->mode,b->mode); 156 a->dir_num = b->dir_num; 157 strcpy(a->user,b->user); 158 strcpy(a->group,b->group); 159 a->size = b->size; 160 strcpy(a->time,b->time); 161 a->st_mode = b->st_mode; 162 strcpy(a->name,b->name); 163 } 164 165 // 排序 166 void sort(LS *info,int index) 167 { 168 LS *temp = (LS*)malloc(sizeof(LS)); 169 for(int i=index-1; i>0; i--) 170 { 171 for(int j=0; j<i; j++) 172 { 173 if(strcmp(info[i].name,info[j].name)<0) 174 { 175 equal(temp,&info[i]); 176 equal(&info[i],&info[j]); 177 equal(&info[j],temp); 178 } 179 } 180 } 181 } 182 183 // 输出结构体 184 void show_ls(LS *info,int index) 185 { 186 for(int i=0; i<index; i++) 187 { 188 //printf("%d: ",i); 189 printf("%s \033[0m",info[i].mode); 190 printf("%d ",info[i].dir_num); 191 printf("%s ",info[i].user); 192 printf("%s ",info[i].group); 193 printf("%5ld ",info[i].size); 194 printf(" %s ",info[i].time); 195 //printf("%d ",info[i].st_mode); 196 if(16893 == info[i].st_mode) 197 { 198 // 颜色 199 printf("\033[34m\033[1m%s\033[0m",info[i].name); 200 } 201 else if(33277 == info[i].st_mode) 202 { 203 printf("\033[32m\033[1m%s\033[0m",info[i].name); 204 } 205 else 206 { 207 printf("%s",info[i].name); 208 } 209 if(i < index) 210 printf("\n"); 211 } 212 //printf("循环结束\n"); 213 } 214 215 // 创建结构体,赋值 216 LS *create(struct stat buf,struct dirent *dirent) 217 { 218 LS* info = (LS*)malloc(sizeof(LS)); 219 char str[50] = {}; 220 //puts(file_mode(buf.st_mode,str)); 221 strcpy(info->mode,file_mode(buf.st_mode,str)); 222 //puts(info->mode); 223 info->dir_num = is_dir(dirent); 224 strcpy(info->user,file_user(buf.st_uid,str)); 225 strcpy(info->group,file_group(buf.st_uid,str)); 226 info->size = file_size(buf); 227 strcpy(info->time,file_time(buf.st_mtime,str)); 228 info->st_mode = buf.st_mode; 229 strcpy(info->name,dirent->d_name); 230 231 return info; 232 } 233 234 int main(int argc,char* argv[]) 235 { 236 LS info[MAX_FILE_NUM]; 237 char* l = "-l"; 238 if(argc != 2) 239 { 240 printf("仅支持传入 -l\n"); 241 return 1; 242 } 243 if(strcmp(argv[1],l) != 0) 244 { 245 printf("\"ls:无法识别的选项\"%s\"\n",argv[1]); 246 printf("请尝试执行\"ls --help\"来获取更多信息。\n"); 247 return 0; 248 } 249 char* a = "."; 250 char* b = ".."; 251 char* path = malloc(10000); 252 strcpy(path,"./"); // 只支持当前路径 253 int count = file_count(path); 254 255 DIR *dir; 256 dir = opendir(path); 257 struct dirent *dirent; 258 int index = 0; // 结构体下标 259 int blocks = 0; 260 for(int i=0; i<count; i++) 261 { 262 dirent = readdir(dir); 263 struct stat buf = {}; 264 if(stat(dirent->d_name,&buf)) 265 { 266 perror("stat"); 267 return -1; 268 } 269 270 // 跳过特殊情况 271 if(strcmp(dirent->d_name,a)==0 || strcmp(dirent->d_name,b)==0) 272 continue; 273 blocks += buf.st_blocks; 274 //printf("%d\n",blocks); 275 info[index++] = *create(buf,dirent); 276 } 277 closedir(dir); 278 //printf("文件总数:%d\n",index); 279 //show_ls(info,index); 280 281 printf("总用量 %d\n",blocks/2); 282 sort(info,index); 283 show_ls(info,index); 284 return 0; 285 }
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论