ls的a l i r R s t 功能的实现

ls

判断是否有路径参数

在这里插入图片描述

optind初值为1,读取一个选项+1(包括选项所带的参数和错误的选项).每个选项字符后可以跟一个冒号字符(:),表示这个选项带有一个参数。

函数返回读取的选项,错误返回(?),optind存储每次读取的选项(包括错误的)。

在这里插入图片描述

检测到一个选项就把该选项的值(全局变量)变为1。

选项-l

在这里插入图片描述

​ 把readdir()的返回值作为参数传给ls_l(),调用stat()。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

​ 把stat结构体中的st_mode和以上常量相与(&),输出文件的类型和权限位。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

​ 把stat结构体中的st_uid传入getpwuid()获取输出struct passwd中的pw_name。同理也可获得组名。

​ 其余信息也都在stat结构体中,时间用ctime()按格式输出

选项-r

在函数内重新调用函数进行递归,即可倒序输出。

选项-i

调用stat(),输出struct stat 中的 st_ino。

选项-s

调用stat(),输出struct stat 中的 st_blocks。

(我的是512字节一块所以输出时除2)

选项-R

遍历完一个目录后,后用rewinddir()再遍历一次如果文件名是“.”或"…“时continue。其他的用stat()获得的st_mode 判断文件类型,如果是目录则chdir()改变工作目录,递归调用opendir(”.“),调用完后chdir(”. .")再返回上一级目录。

选项-a

a=0时,如果文件名为".“或”. ."或第一个字符为’.',continue。

选项-t

先遍历一遍,得到该目录下一共有几个文件,新建一个结构体包括st_mtime和struct dirent *ent,动态分配相应大小的内存。然后rewinddir()在遍历一遍,把st_mtime和struct dirent *ent存入结构体数组。用qsort()给它降序排序。

遇到的问题

1.qsort()

​ 我写的qsort() 和cmp()应该是没问题的,但就是没排序,不得已用网上找的冒泡。(是Linux自带的头文件有问题吗??)

2.局部变量全局变量名相同

表示选项-i的全局变量i和循环变量i相同,导致不明意义的输出i节点号。

3.malloc()完之后要free()

不然会段错误 或"malloc(): corrupted top size"。

4.cv后记得改变量名

从别的函数cv过来后变量没有改为该函数内对应的变量名。

5.在chdir()后应opendir(“.”)

改变工作目录后又打开了工作目录的名字: “. .”(或是含路径的参数)会输出错误的路径里的内容。

以下为代码实现

#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>

typedef struct t{
    time_t time;
    struct dirent * Ent;
}file;


int a,l,t,r,i,s,R,R0;
//long long int blocks;
int cmp(const void *a,const void *b);
void ls_t(DIR *dir);
void ls_R(struct dirent *ent);
int ls_s(struct dirent *ent);
void ls_l(struct dirent *ent);
void ls_read(DIR *dir);
void ls_open(char *dir_path);
void Bubble_sort(file list[],int N);


 void Bubble_sort(file list[],int N){
    int i, j;
    file t;
    // N 娑擃亜鍘撶槐鐙呯礉闁秴宸� N-1 濞嗭拷
    for (i = 0; i < N - 1; i++) {
        // 娴犲海顑� 1 娑擃亜鍘撶槐鐘茬磻婵浜堕崢鍡礉闁秴宸婚懛锟� N-1-i
        for (j = 0; j < N - 1 - i; j++) {
            //濮f棁绶� list[j] 閸滐拷 list[j+1] 閻ㄥ嫬銇囩亸锟�
            if (list[j].time < list[j + 1].time) {
                //娴溿倖宕� 2 娑擃亜鍘撶槐鐘垫畱娴e秶鐤�
                t = list[j];
                list[j] = list[j + 1];
                list[j + 1] = t;
            }
        }
    }
}

int cmp(const void *a,const void *b){
    file *aa=(file *)a;
    file *bb=(file *)b;
    return (bb->time-aa->time);
}

//时间顺序
void ls_t(DIR *dir){
    int mount=0;
    struct dirent *ent; 
    while ((ent = readdir(dir)) != NULL) {
        mount++;
        }
        file *fil=(file *)malloc((mount)*sizeof(file));
        mount=0;
        rewinddir(dir);
        int t=0;
        while((ent = readdir(dir)) != NULL){
            struct stat statbuf;
            stat(ent->d_name,&statbuf);
            fil[t].time=statbuf.st_mtime;
            fil[t].Ent=ent;
            t++;
        }

         Bubble_sort(fil,t); 
        // for(int i=0;i<t;i++){
        //     printf("%lu     ",fil[i].time);
        // }
        // printf("\n");
        //   //qsort(fil,t,sizeof(file),cmp);//为什么不排序
        // for(int i=0;i<t;i++){
        //     printf("%lu     ",fil[i].time);
        // }
        int blocks=0;
        if(r==0){
           for(int i1=0;i1<t;i1++){
            
        if(a==0){
            if(strcmp(fil[i1].Ent->d_name,".")==0||strcmp(fil[i1].Ent->d_name,"..")==0||fil[i1].Ent->d_name[0]=='.')
            continue;
        }
        if(i==1){//没有选项-i但会在循环到ls.c时//在循环时i会不规律递增//循环变量名和-i选项重叠
            printf("%lu  ",fil[i].Ent->d_ino);
        }
        if(s==1){
            blocks+=ls_s(fil[i1].Ent);
        }
        if(l==1){
            ls_l(fil[i1].Ent);
        }
        
        printf("%s  ", fil[i1].Ent->d_name);
        if(l==1) printf("\n");
        }
        if(s==1){
            printf("\n总用量:  %d",blocks);
            blocks=0;
        }
        if(R==1){
            if(R0==1) printf("    结束\n");
            if(R0==0) R0=1;
        for(int i1=0;i1<t;i1++){
            if(a==0&&fil[i1].Ent->d_name[0]=='.') continue;//cv后变量没有改为该函数内对应的变量名
            if(strcmp(fil[i1].Ent->d_name,".")==0||strcmp(fil[i1].Ent->d_name,"..")==0)
            continue;
            ls_R(fil[i1].Ent);
        }
        }
        }
        
        

        if(r==1){
            for(int i1=t-1;i1>=0;i1--){
            if(a==0){
            if(strcmp(fil[i1].Ent->d_name,".")==0||strcmp(fil[i1].Ent->d_name,"..")==0||fil[i1].Ent->d_name[0]=='.')
            continue;
        }
        if(i==1){
            printf("%lu  ",fil[i1].Ent->d_ino);
        }
        if(s==1){
            blocks+=ls_s(fil[i1].Ent);
        }
        if(l==1){
            ls_l(fil[i1].Ent);
        }
        printf("%s  ", fil[i1].Ent->d_name);
        
        
        if(l==1) printf("\n");
        }
        if(s==1){
            printf("\n总用量:  %d",blocks);
            blocks=0;
        }
        if(R==1){
            if(R0==1) printf("    结束\n");
            if(R0==0) R0=1;
        for(int i1=0;i1<t;i1++){
            if(a==0&&fil[i1].Ent->d_name[0]=='.') continue;
            if(strcmp(fil[i1].Ent->d_name,".")==0||strcmp(fil[i1].Ent->d_name,"..")==0)
            continue;
            ls_R(fil[i1].Ent);
        }
            
        }
        }

        
        free(fil);
}

//打开子目录
//如果是链接,不打开???
void ls_R(struct dirent *ent){
    struct stat statbuf;
    stat(ent->d_name,&statbuf);
    if(S_ISDIR(statbuf.st_mode)){// &&strcmp(ent->d_name,".")!=0&&strcmp(ent->d_name,"..")!=0
        char name[100];
        printf("\n%s/%s:\n",getcwd(name,100),ent->d_name);
        chdir(ent->d_name);
        ls_open(".");
        chdir("..");
    }
    
}

//块大小
//改为单个目录大小
int ls_s(struct dirent *ent){
    struct stat statbuf;
stat(ent->d_name,&statbuf);
printf("%lu  ",statbuf.st_blocks/2);
return statbuf.st_blocks/2;
}

//详细属性
void ls_l(struct dirent *ent){
    struct stat statbuf;
stat(ent->d_name,&statbuf);
        switch (statbuf.st_mode & S_IFMT)
    {
        case S_IFREG:
            printf("-");
            break;
        case S_IFCHR:
            printf("c");
            break;
        case S_IFBLK:
            printf("b");
            break;
        case S_IFDIR:
            printf("d");
            break;
        case S_IFIFO:
            printf("p");
            break;
        case S_IFLNK:
            printf("l");
            break;
        case S_IFSOCK:
            printf("s");
            break;
    }
    if(statbuf.st_mode&S_IRUSR)printf("r");else printf("-");
    if(statbuf.st_mode&S_IWUSR)printf("w");else printf("-");
    if(statbuf.st_mode&S_IXUSR)printf("x");else printf("-");
    if(statbuf.st_mode&S_IRGRP)printf("r");else printf("-");
    if(statbuf.st_mode&S_IWGRP)printf("w");else printf("-");
    if(statbuf.st_mode&S_IXGRP)printf("x");else printf("-");
    if(statbuf.st_mode&S_IROTH)printf("r");else printf("-");
    if(statbuf.st_mode&S_IWOTH)printf("w");else printf("-");
    if(statbuf.st_mode&S_IXOTH)printf("x");else printf("-");
      struct passwd *pw = getpwuid(statbuf.st_uid);
    struct group *gr = getgrgid(statbuf.st_gid);
            printf("  %lu  %s  %s  %ld  %s",statbuf.st_nlink,pw->pw_name,gr->gr_name,statbuf.st_blksize,ctime(&statbuf.st_mtime));
            // free(pw);
            // free(gr);
}

void ls_read(DIR *dir){
    struct dirent *ent; 
    int blocks=0;
     while ((ent = readdir(dir)) != NULL) {
        if(r==1){
            ls_read(dir);//while 改掉
        }
        if(a==0){
            if(strcmp(ent->d_name,".")==0||strcmp(ent->d_name,"..")==0||ent->d_name[0]=='.')
            continue;
        }
        if(i==1){
            printf("%lu  ",ent->d_ino);
        }
        if(s==1){
            blocks+=ls_s(ent);
        }
        if(l==1){
            ls_l(ent);
        }
        printf("%s  ", ent->d_name);
        if(l==1) printf("\n");
        }
        if(s==1){
            printf("\n总用量:  %d",blocks);
            blocks=0;
        }
        if(R==1){
            if(R0==1) printf("    结束\n");
            if(R0==0) R0=1;
            rewinddir(dir);
        while((ent=readdir(dir))!=NULL){
            if(a==0&&ent->d_name[0]=='.') continue;
            if(strcmp(ent->d_name,".")==0||strcmp(ent->d_name,"..")==0)
            continue;
            ls_R(ent);
        }
            
        }
        
        
}

void ls_open(char *dir_path){
    DIR *dir;
    if ((dir = opendir(dir_path)) != NULL) {
        if(t==1){
            ls_t(dir);
        }else {
            ls_read(dir);
        } 
        closedir(dir);
    } else {
        perror("打开目录失败");
        exit(EXIT_FAILURE);
    }
}

int main(int argc, char *argv[]) {
    DIR *dir;
    struct dirent *ent;
    char *dir_path = ".";
   int opt,opterr=0;

    while ((opt = getopt(argc, argv, "alRtris")) != -1) {
        switch (opt) {
            case 'a':
                a=1;
                break;
            case 'l':
                l=1;
                break;
            case 'R':
                R=1;
                break;
            case 't':
                t=1;
                break;
            case 'r':
                r=1;
                break;
            case 'i':
                i=1;
                break;
            case 's':
                s=1;
                break;
            case '?':
                printf("Unknown option: %c\n", optopt);
                break;
        }
    }

    if (optind<argc&&argc!=1){
        dir_path=argv[optind];
        chdir(dir_path);
    }
               ls_open(".");//改变工作目录后又打开了工作目录的名字 ".."(含路径的参数)会出错
               printf("\n");
    return EXIT_SUCCESS;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值