zoukankan      html  css  js  c++  java
  • C语言实现ls之myls改进

    C语言实现ls之myls改进

    20191331 lyx

    在之前的系统调用实践中已经实现myls-l命令

    但该命令实现的并不完美,只能查看单一文件,且工程代码没有实现模块化

    具体情况如下:

    源代码链接:https://gitee.com/DKY2019/xxaqxt/blob/master/myls_l.c

    现为实现完整的 ls-l 命令,做如下改进:

    • 代码模块化
    • 执行 ls -l ./ 打印目录下所有文件

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <dirent.h>
    #include <sys/stat.h>
    #include <utime.h>
    #include <time.h>
    #include <pwd.h>
    #include <grp.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <errno.h>
    #include <string.h>
    
    
    int print_type(mode_t st_mode){
        char perms[11]={0}; 
        switch (st_mode & S_IFMT){
            case S_IFLNK:
                perms[0]='l';
                break;
            case S_IFDIR:
                perms[0]='d';
                break;
            case S_IFREG:
                perms[0]='-';
                break;
            case S_IFBLK:
                perms[0]='b';
                break;
            case S_IFCHR:
                perms[0]='c';
                break;
            case S_IFSOCK:
                perms[0]='s';
                break;
            case S_IFIFO:
                perms[0]='p';
                break;
            default:
                perms[0]='?';
                break;
        }
        
        perms[1]=(st_mode & S_IRUSR) ? 'r':'-';
        perms[2]=(st_mode & S_IWUSR) ? 'w':'-';
        perms[3]=(st_mode & S_IXUSR) ? 'x':'-';
        perms[4]=(st_mode & S_IRGRP) ? 'r':'-';
        perms[5]=(st_mode & S_IWGRP) ? 'w':'-';
        perms[6]=(st_mode & S_IXGRP) ? 'x':'-';
        perms[7]=(st_mode & S_IROTH) ? 'r':'-';
        perms[8]=(st_mode & S_IWOTH) ? 'w':'-';
        perms[9]=(st_mode & S_IXOTH) ? 'x':'-';
      printf("%s ", perms);
      return 0;
    }
    
    int print_info(struct stat currentstat){
      struct passwd *p_passwd;
      struct group *p_group;
      char *p_time;
      int i;
      p_time = ctime(&currentstat.st_mtime);
      p_passwd = getpwuid(currentstat.st_uid);
      p_group = getgrgid(currentstat.st_gid);       
      printf("%d ",(int)currentstat.st_nlink);
      if(p_passwd != NULL)
    	printf("%s ",p_passwd->pw_name);
      else
    	printf("%d ",(int)currentstat.st_uid);
      if(p_group != NULL)
    	printf("%s ",p_group->gr_name);
      else
    	printf("%d ",currentstat.st_gid);
      printf("%7d ",(int)currentstat.st_size);
      for(i=0; p_time[i] !=0 && p_time[i]!='
    '; i++){
    	  putchar(p_time[i]);
      }
    
      return 0;
    }
    
    int main(int argc, char* argv[]){
      char buf[500];
      DIR *currentdir = NULL;
      struct dirent *currentdp = NULL;
      struct stat currentstat;
    
    
    
      if(argc != 2)
      {
         printf("%s need filename
    ",argv[0]);
         exit(1);
      }
      memset(buf,0,500); 
      sprintf(buf,"%s",argv[1]);
      currentdir = opendir(buf);
      if(currentdir == NULL){
         printf("open directory fail
    ");
         return 0;
      }
    
    
      while((currentdp = readdir(currentdir)) != NULL)
     {
      if(currentdp->d_name[0] != '.')
     {
        sprintf(buf,"%s/%s",buf,currentdp->d_name);
      if(lstat(buf,&currentstat) == -1){
        printf("the dir:%s :",buf);
        printf("get stat error
    ");
        continue;
      }
    
      lstat(buf,&currentstat);
    
    
      
      print_type(currentstat.st_mode);        
      print_info(currentstat);
      printf("  ");
      printf("%s
    ", currentdp->d_name);
     
      memset(buf,0,500);
      sprintf(buf,"%s",argv[1]);
      
     }//if end
     }//while end
      closedir(currentdir);
      return 0;
    }
    

    码云链接:https://gitee.com/DKY2019/xxaqxt/blob/master/myls相关练习/myls_l-2.c

    执行效果:

    完善myls

    • 文件名读入数组,qsort()排序(为复习C语言,qsort手工完成,参考)
    • 加入-a选项
    • 计算列宽和行数

    代码:

    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<dirent.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<string.h>
    #include<time.h>
    #include<pwd.h>
    #include<grp.h>
    
    char *uid_to_name(uid_t uid)
    {
       struct passwd * getpwuid(),*pw_ptr;
       static char numstr[10];
    
       if((pw_ptr= getpwuid(uid))==NULL)
       {
           sprintf(numstr,"%d",uid);
           return numstr;
       }
       else
           return pw_ptr->pw_name;
    }
    
    char *gid_to_name(gid_t gid)
    {
       struct group *getgrgid(),*grp_ptr;
       static char numstr[10];
       if((grp_ptr=getgrgid(gid))==NULL)
       {
           sprintf(numstr,"%d",gid);
           return numstr;
       }
       else
           return grp_ptr->gr_name;
    }
    
    int find_mid(char(*data)[512], int l, int r)
    {
        int mid = (l + r) / 2;
        if(strcmp(data[l], data[mid]) > 0)
        {
            int t = l;
            l = mid;
            mid = t;
        }
        if(strcmp(data[mid], data[r]) > 0)
        {
            int t = mid;
            mid = r;
            r = t;
        }
        return mid;
    }
    
    void swap(char *a, char *b)
    {
        char t[512];
        strcpy(t, a);
        strcpy(a, b);
        strcpy(b, t);
    }
    void sort(char(*data)[512], int l, int r)
    {
        while(l < r)
        {
            int x = l, y = r;
            int mid = find_mid(data, l, r);
            do
            {
                while(strcmp(data[y], data[mid]) > 0)
                    y--;
                while(strcmp(data[x], data[mid]) < 0)
                    x++;
                if(x <= y)
                {
                    swap(data[x++], data[y--]);
                }
            }
            while(x <= y);
            sort(data, x, r);
            r = y;
        }
    }
    int check_filename_color(int mode_bit)
    {
        int file_type = (mode_bit & 0170000);
        if(file_type == 0040000) return 2;
        if(mode_bit & 0000111) return 1;
        return 0;
    }
    
    void printdir(char* dirname, int is_all)
    {
        char pathname[512];
        char names[256][512];
        int cnt_name = 0;
        DIR* dir;
        struct dirent* dp;
        struct stat st;
        if(!(dir = opendir(dirname)))
        {
            perror("opendir");
            exit(1);
        }
        //weather filter "." ".."
        while(dp = readdir(dir))
        {
            if(!is_all && dp -> d_name[0] == '.')
                continue;
            strcpy(names[cnt_name++], dp -> d_name);
        }
    
        sort(names, 0, cnt_name - 1);
        //printf("[%s]
    ", names[0]);
    
        for(int i = 0; i < cnt_name; i++)
        {
            sprintf(pathname, "%s/%s", dirname, names[i]);
            if(stat(pathname, &st) == -1)
            {
                perror("stat");
                exit(1);
            }
            int filename_color = check_filename_color(st.st_mode);
            if(filename_color == 1)
            {
                printf("33[1;32m%s33[0m  ", pathname + 2);
            }
            else if(filename_color == 2)
            {
                printf("33[1;34m%s33[0m  ", pathname + 2);
            }
            else printf("%s  ", pathname + 2);
    
        }
        closedir(dir);
        printf("
    ");
    }
    int main(int argc, char* argv[])
    {
        int is_all = 0;
        if(argc == 1)
        {
            printdir(".", is_all);
            return 0;
        }
        if(argc > 1)
        {
            for(int i = 1; i < argc; i++)
            {
                if(argv[i][0] != '-') continue;
                for(int j = 1; argv[i][j]; j++)
                {
                    if(argv[i][j] == 'a') is_all = 1;
                    else
                    {
                        printf("invalid option, please check again!
    ");
                        exit(1);
                    }
                }
            }
        }
        int flag = 0;
        for(int i = 1; i < argc; i++)
        {
            if(argv[i][0] == '-') continue;
            flag = 1;
            printdir(argv[i], is_all);
        }
        if(!flag) printdir(".", is_all);
        return 0;
    }
    

    码云链接:https://gitee.com/DKY2019/xxaqxt/blob/master/myls相关练习/myls-2.c

    执行效果:

    参考资料

    qsort使用方法 https://blog.csdn.net/C_time/article/details/88428100
    C语言实现qsort https://blog.csdn.net/qq_43632625/article/details/93140277

  • 相关阅读:
    第1课 Git、谁与争锋
    程序员最真实的10个瞬间
    程序员最真实的10个瞬间
    一文读懂前端缓存
    一文读懂前端缓存
    一文读懂前端缓存
    EF使用CodeFirst创建数据库和表
    EF使用CodeFirst创建数据库和表
    EF使用CodeFirst创建数据库和表
    ASP.NET MVC的过滤器笔记
  • 原文地址:https://www.cnblogs.com/DKYcaiji/p/15518127.html
Copyright © 2011-2022 走看看