作业需求:
要求输入目录路径以及名字,能够将该路径下所有文件的属性打印出来,类似ls -l
实现过程:
08_statfunction.c(声明函数)
#ifndef __STATFUNC_H__
#define __STATFUNC_H__
//获取文件的权限
char* get_filePermission(mode_t mode, char* pstr);
//获取文件的类型
char get_fileType(mode_t mode);
//让月份变为中文
void get_month(int t1);
//文件所属用户
void get_uid(mode_t uid);
//文件所属组用户
void get_gid(mode_t gid);
//文件的时间
void get_time(time_t te);
#endif
07 _statfunction.c(封装函数)
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
//获取文件的权限
//char pstr[]相当于char* pstr,
//char pstr[10]作为形参,用于提示用户,需要传一个字符数组首地址进来,且容量为10;
//char pstr[10]其实相当于char* ptr;
char* get_filePermission(mode_t mode, char pstr[10])
{
// printf("sizeof(pstr)=%ld\n", sizeof(pstr)); //8,即指针的大小
char m[4] = "rwx";
for(int i=0; i<9; i++)
{
if((mode& (0400>>i)) == 0)
{
pstr[i] = '-';
continue;
}
//能运行到当前位置,则代表mode&(0400>>i)是不等于0;
pstr[i] = m[i%3];
/*
switch(i%3)
{
case 0:
putchar('r');
break;
case 1:
putchar('w');
break;
case 2:
putchar('x');
break;
}
*/
}
return pstr;
}
/*{{{
void get_filePermission(mode_t mode)
{
//当前用户的权限
if((mode & 0400) !=0)
putchar('r');
else
putchar('-');
if((mode & 0200) != 0)
putchar('w');
else
putchar('-');
if((mode & 0100) != 0)
putchar('x');
else
putchar('-');
//组用户的权限
if((mode & 0040) !=0)
putchar('r');
else
putchar('-');
if((mode & 0020) != 0)
putchar('w');
else
putchar('-');
if((mode & 0010) != 0)
putchar('x');
else
putchar('-');
//其他用户的权限
if((mode & 0004) !=0)
putchar('r');
else
putchar('-');
if((mode & 0002) != 0)
putchar('w');
else
putchar('-');
if((mode & 0001) != 0)
putchar('x');
else
putchar('-');
return;
}
*//*}}}*/
//获取文件的类型
char get_fileType(mode_t mode)
{
char c = 0;
switch(mode&S_IFMT)
{
case S_IFSOCK: c = 's'; break;
case S_IFLNK: c = 'l'; break;
case S_IFREG: c = '-'; break;
case S_IFDIR: c = 'd'; break;
}
return c;
}
/*{{{
char get_fileType(mode_t mode)
{
if(S_ISREG(mode))
return '-';
else if(S_ISDIR(mode))
return 'd';
else if(S_ISCHR(mode))
return 'c';
}
*//*}}}*/
//让月份变为中文
void get_month(int t1)
{
switch(t1)
{
case 1 :
printf("一\t");
break;
case 2 :
printf("二\t");
break;
case 3 :
printf("三\t");
break;
case 4 :
printf("四\t");
break;
case 5 :
printf("五\t");
break;
case 6 :
printf("六\t");
break;
case 7 :
printf("七\t");
break;
case 8 :
printf("八\t");
break;
case 9 :
printf("九\t");
break;
case 10 :
printf("十\t");
break;
case 11 :
printf("十一\t");
break;
case 12 :
printf("十二\t");
break;
default:
printf("error\t");
break;
}
}
//文件所属用户
void get_uid(mode_t uid)
{
struct passwd* pwd = getpwuid(uid);
if(NULL == pwd)
{
perror("getpwuid");
return ;
}
printf("%s\t", pwd->pw_name);
}
//文件所属组用户
void get_gid(mode_t gid)
{
struct group* grp = getgrgid(gid);
if(NULL == grp)
{
perror("getgrgid");
return ;
}
printf("%s\t", grp->gr_name);
}
//文件的时间
void get_time(time_t te)
{
time_t t;
struct tm* info = NULL;
t=te;
info=localtime(&t);
int t1=(info->tm_mon+1);
get_month(t1);
printf("%d\t",info->tm_mday);
printf("%d:%d\t",info->tm_hour,info->tm_min);
}
06 _stat.c(测试函数)
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include "./08_statfunc.h"
#include <time.h>
#include <error.h>
#include <dirent.h>
//<> 和 ""的区别:
//<>:到标准库目录下查找头文件:/usr/include/
//"":先到制定目录下查找头文件,如果找不到,则到标准库目录下查找
int main(int argc, const char *argv[])
{
if(argc<2)
{
printf("请在命令行输入目录名\n");
return -1;
}
DIR * dp = opendir(argv[1]);
if(NULL==dp)
{
perror("opendir");
return -1;
}
//读取目录
struct dirent *rp=NULL;
while(1)
{
rp=readdir(dp);
if(rp==NULL)
{
if(error!=0)
{
perror("readdir");
return -1;
}
else
{
break;
}
}
struct stat buf;
if(stat(rp->d_name, &buf) < 0)
{
perror("stat");
return -1;
}
char per[10] = "";
char type = 0;
//文件的类型以及权限
type = get_fileType(buf.st_mode);
printf("%c", type);
get_filePermission(buf.st_mode, per);
printf("%s\t", per);
//文件的硬链接数
printf("%ld\t", buf.st_nlink);
//文件所属用户
get_uid(buf.st_uid);
//文件所属组用户
get_gid(buf.st_gid);
//文件的大小
printf("%ld\t", buf.st_size);
//文件的时间
get_time(buf.st_atime);
//文件名
printf("%s\t",argv[1]);
printf("\n");
}
return 0;
}
实现结果如下:
ubuntu@ubuntu:03_day$ gcc 06_stat.c 07_statfunc.c
ubuntu@ubuntu:03_day$ ./a.out
请在命令行输入目录名
ubuntu@ubuntu:03_day$ ./a.out ./
drwxrwxr-x 6 ubuntu ubuntu 4096 十二 8 9:24 ./
-rwxrwxrwx 1 ubuntu ubuntu 0 十二 7 9:50 ./
-rwxrwxr-x 1 ubuntu ubuntu 13160 十二 8 18:52 ./
-rw-rw-r-- 1 ubuntu ubuntu 692 十二 8 15:26 ./
-rw-rw-r-- 1 ubuntu ubuntu 803 十二 7 21:2 ./
-rw-rw-r-- 1 ubuntu ubuntu 426 十二 7 10:41 ./
-rw------- 1 ubuntu ubuntu 380 十二 7 20:26 ./
drwxrwxr-x 2 ubuntu ubuntu 4096 十二 7 17:15 ./
-rwxrwxr-x 1 ubuntu ubuntu 10 十二 7 11:55 ./
-rw-rw-r-- 1 ubuntu ubuntu 6 十二 7 14:33 ./
-rw-rw-r-- 1 ubuntu ubuntu 84 十二 7 17:11 ./
-rw------- 1 ubuntu ubuntu 3133 十二 7 20:19 ./
-rw-rw-r-- 1 ubuntu ubuntu 1958928 十二 7 15:48 ./
-rw-rw-r-- 1 ubuntu ubuntu 584 十二 7 17:11 ./
drwxrwxr-x 3 ubuntu ubuntu 4096 十二 8 18:52 ./
-rwxrwxr-x 1 ubuntu ubuntu 11 十二 7 21:1 ./
-rw------- 1 ubuntu ubuntu 1367 十二 8 18:52 ./
-rw-rw-r-- 1 ubuntu ubuntu 534 十二 7 14:46 ./
-rw-rw-r-- 1 ubuntu ubuntu 276 十二 7 15:49 ./
readdir: Success
ubuntu@ubuntu:03_day$