linux 用函数写出 ls -l 命令 的文件属性 (~~~超级详细)(下)

好啦,不吊大家胃口了~先贴代码:

     s=buf.st_mode;  
     int d,u,g,o,i;  
     o=s%8;                                                                                                                                     
     g=s/8%8;
     u=s/8/8%8;
     int a[3];
     a[0]=u;a[1]=g;a[2]=o;
     for(i=0;i<3;i++)
     {
         switch(a[i])
         {
            case 0:printf("---");break;
            case 1:printf("--x");break;
            case 2:printf("-w-");break;
            case 3:printf("-wx");break;
            case 4:printf("r--");break;
            case 5:printf("r-x");break;
            case 6:printf("rw-");break;
            case 7:printf("rwx");break;
         }
     }

很简单的吧对不对!!!   Σ(っ °Д °;)っ

好啦,解释一下,就是将刚才那 st_mode 的五位数字中代表三种权限的最后三位数字分离出来

用的是最基本的 取余 % ;只不过要注意的点就是

因为是八进制,所以是 %8 ,而不是我们平时做的%10哦      (´ー∀ー`)

好啦,最繁琐的部分已经结束了,接下来就是直接按需求从 buf 结构体里输出了

4.连到该文件的硬链接数目就可以直接输出

   printf("%d  ",buf.st_nlink);

5.emmmmmm 忘了 ,还有 用户用户组。。。。。。

它们两个在结构体中都只是ID的形式,所以,我们需要将它们转换成名称

只需要两个函数就可以啦~~

getpwuid()函数和 getgrgid()函数

记得不要忘记补充上它们两个没有的头文件

#include<grp.h>
#include <stdlib.h>
`   struct passwd *psd;
    struct group *grp;
    psd=getpwuid(buf.st_uid);
    grp=getgrgid(buf.st_gid);

这两个结构体里储存的是用户和用户组的信息,如果只要输出名称的话

记得要这样输出:

    printf("%s",psd->pw_name);
    printf("%s",grp->gr_name);

6.内存大小也是直接输出的:

printf("%d  ",buf.st_size);

7.输出时间时,是需要再添加头文件

#include<string.h>
#include<time.h>

用到ctime函数,将时间和日期转换为字符串;

但是直接输出得到的字符串会发现有秒啊、年啊那些不用显示出来的时间,所以自己可以输出试试,

看看需要打印出来的是从第几位到第几位

    char time[100];
    strcpy(time,ctime(&buf.st_mtime));
    printf("%s",time);
    for(i=4;i<16;i++)
 	printf("%c",time[i]);

最后再把文件名打印出来就好啦;

 

整体代码:

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

void my_err(const char *s,int line)
{
    fprintf(stderr,"line:%d",line);
    perror(s);
    exit(1);
}


int main()
{
    char file_name[100]; char time[100];
    int d,u,g,o,i,s;
    int a[3];
    struct passwd *psd;
    struct group *grp;
    struct stat buf;
    printf("请输入正确的文件或目录名称:\n");
	scanf("%s",file_name);

    if(stat(file_name,&buf)==-1)
    {
        my_err("stat",__LINE__);
    }

    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");
  
    s=buf.st_mode;
    o=s%8;
    g=s/8%8;
    u=s/8/8%8;
    a[0]=u;a[1]=g;a[2]=o;
    for(i=0;i<3;i++)
    {
	    switch(a[i])
	    {
		    case 0:printf("---");break;
		    case 1:printf("--x");break;
		    case 4:printf("r--");break;
		    case 2:printf("-w-");break;
		    case 3:printf("-wx");break;
		    case 5:printf("r-x");break;
		    case 6:printf("rw-");break;
		    case 7:printf("rwx");break;
	    }
    }

    psd=getpwuid(buf.st_uid);
    grp=getgrgid(buf.st_gid);

    printf("%4d  ",buf.st_nlink);
    printf("%-8s",psd->pw_name);
    printf("%-8s",grp->gr_name);
    printf("  %6d  ",buf.st_size);

    strcpy(time,ctime(&buf.st_mtime));
    for(i=4;i<16;i++)
 	    printf("%c",time[i]);
    printf("  %s\n",file_name);
}

关于月份中文这个问题~~~因为我的Linux版本显示的是中文

所以想要得到中文的自己再写一个if ~~~ else if 把12个月对应吧......这个随便的(。・_・)/~~~

还有文件颜色......喜欢的童鞋自己去研究吧~~~我不管

ヾ( ̄▽ ̄)Bye~Bye~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是一个简单的实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <pwd.h> #include <grp.h> #include <time.h> int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s <directory>\n", argv[0]); exit(EXIT_FAILURE); } DIR *dir; struct dirent *entry; struct stat sb; char buf[512]; if ((dir = opendir(argv[1])) == NULL) { perror("opendir"); exit(EXIT_FAILURE); } while ((entry = readdir(dir)) != NULL) { sprintf(buf, "%s/%s", argv[1], entry->d_name); if (stat(buf, &sb) == -1) { perror("stat"); continue; } printf("%c%c%c%c%c%c%c%c%c%c %ld ", S_ISDIR(sb.st_mode) ? 'd' : '-', sb.st_mode & S_IRUSR ? 'r' : '-', sb.st_mode & S_IWUSR ? 'w' : '-', sb.st_mode & S_IXUSR ? 'x' : '-', sb.st_mode & S_IRGRP ? 'r' : '-', sb.st_mode & S_IWGRP ? 'w' : '-', sb.st_mode & S_IXGRP ? 'x' : '-', sb.st_mode & S_IROTH ? 'r' : '-', sb.st_mode & S_IWOTH ? 'w' : '-', sb.st_mode & S_IXOTH ? 'x' : '-', sb.st_nlink); struct passwd *pw = getpwuid(sb.st_uid); if (pw != NULL) { printf("%s ", pw->pw_name); } else { printf("%d ", sb.st_uid); } struct group *gr = getgrgid(sb.st_gid); if (gr != NULL) { printf("%s ", gr->gr_name); } else { printf("%d ", sb.st_gid); } printf("%ld ", sb.st_size); struct tm *tm = localtime(&sb.st_mtime); char time_buf[32]; strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", tm); printf("%s ", time_buf); printf("%s\n", entry->d_name); } closedir(dir); exit(EXIT_SUCCESS); } ``` 该程序使用 `opendir()` 和 `readdir()` 函数打开并读取指定目录中的所有文件和子目录,然后对每个文件(夹)使用 `stat()` 函数获取其属性信息并打印出来。对于文件类型,程序根据 `st_mode` 字段中的 `S_ISDIR()` 宏来判断是否为目录。对于权限,程序使用 `st_mode` 字段中的各个标志位来判断是否具有读、写和执行权限。对于所有者用户名和所在组用户名,程序使用 `getpwuid()` 和 `getgrgid()` 函数分别获取其对应的 `passwd` 和 `group` 结构体,并从中获取用户名。对于文件大小,程序使用 `st_size` 字段。对于最后修改时间,程序使用 `st_mtime` 字段,并使用 `localtime()` 和 `strftime()` 函数将其格式化为字符串。最后,程序打印出文件(夹)名。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值