zoukankan      html  css  js  c++  java
  • 高仿linux下的ls -l命令——C语言实现

    主要用到的函数可以参考头文件,仅仅支持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] = '';
     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 33[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("33[34m33[1m%s33[0m",info[i].name);
    200         }
    201         else if(33277 == info[i].st_mode)
    202         {
    203             printf("33[32m33[1m%s33[0m",info[i].name);
    204         }
    205         else
    206         {
    207             printf("%s",info[i].name);
    208         }
    209         if(i < index)
    210             printf("
    ");
    211     }
    212     //printf("循环结束
    ");
    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
    ");
    241         return 1;
    242     }
    243     if(strcmp(argv[1],l) != 0)
    244     {
    245         printf(""ls:无法识别的选项"%s"
    ",argv[1]);
    246         printf("请尝试执行"ls --help"来获取更多信息。
    ");
    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
    ",blocks);
    275         info[index++] = *create(buf,dirent);
    276     }
    277     closedir(dir);
    278     //printf("文件总数:%d
    ",index);
    279     //show_ls(info,index);    
    280 
    281     printf("总用量 %d
    ",blocks/2);
    282     sort(info,index);
    283     show_ls(info,index);
    284     return 0;
    285 }
  • 相关阅读:
    1010 幂次方
    1316 丢瓶盖
    1182 数列分段2
    Mysql动态SQL语句标签
    知了CMS开发说明文档(ibeetl) 建站系统文档
    BeanUtils.populate()的用法
    如何将网页的title前面的图标替换成自己公司的图标
    HTTP、HTTPS常用的默认端口号
    项目的xml文件中经常使用的sql语句
    Invalid bound statement(not found): com.xxx.xxx.xxx.xxxMapper.save
  • 原文地址:https://www.cnblogs.com/ikaros-521/p/11254332.html
Copyright © 2011-2022 走看看