需求:
使用文件IO函数打印任意类型文件的属性信息
代码实现过程:
func.h:
#ifndef __FUNC_H__
#define __FUNC_H__
//提取文件权限
char *get_FilePermission(mode_t mode,char pstr[10]);
//提取文件类型
char get_FileType(mode_t mode);
//提取文件所属用户
char *get_Filepwname(uid_t uid,char pstr[32]);
//提取文件所属组用户
char *get_Groupname(uid_t uid,char pstr[32]);
//转换文件时间至日历
void *get_calendar(time_t ctim);
#endif
func.c:
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#define MSG_ERR(msg){\
fprintf(stderr,"line : %d",__LINE__);\
perror("msg");\
}
//提取文件权限
char *get_FilePermission(mode_t mode,char pstr[10]){// 2.返回值char*,形参为char pstr[10]的形式\
起提示作用,提示在主函数传入一个数组\
且长度为10
int a = 0400;
char str[3]={'r','w','x'};
int i=0;
while(i<9){
if((mode & a))
//putchar(str[(i)%3]);
pstr[i]=str[i%3]; //若有权限,通过模除获得对应权限
else
//putchar('-');
pstr[i]='-'; //若无权限,直接获得'-'
a=a>>1; //不断右移动,以以计算下一个权限
i++;
}
//putchar(10);
return pstr; //传回主函数传进的地址
}
//提取文件类型
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;
case S_IFBLK: c = 'b'; break;
case S_IFCHR: c = 'c'; break;
case S_IFIFO: c = 'p'; break;
default:printf("unknown?\n");break;
}
return c;
}
//提取文件所属用户
char *get_Filepwname(uid_t uid,char pstr[32]){
struct passwd* pwd = getpwuid(uid);
if(pwd==NULL){
MSG_ERR(getpwuid);
}
//char str[32]=pwd->pw_name;
strcpy(pstr,pwd->pw_name);
//return pstr;
//printf("%s\n",pwd->pw_name);
return pstr;
}
//提取文件所属组用户
char *get_Groupname(gid_t gid,char pstr[32]){
struct group* grp = getgrgid(gid);
if(grp==NULL){
MSG_ERR(getgrgid);
}
strcpy(pstr,grp->gr_name);
return pstr;
}
//转换文件时间至日历
void *get_calendar(time_t ctim){
char *mon[]={"一","二","三","四","五","六","七","八","九","十","十一","十二"}; //定义一个指针数组,每个指针指向一个字符串
struct tm* info = NULL;
info = localtime(&ctim); //获得日历结构体,并打印需要的成员
printf("%s %2d %02d:%02d ",mon[info->tm_mon],info->tm_mday,info->tm_hour,info->tm_min);
}
StatCap.c:
#include<stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "func.h"
int main(int argc, const char *argv[])
{
struct stat buf;
if( argc < 2 ){
printf("请在终端输入路径或文件名\n");
return -1;
}
if(stat(argv[1],&buf)<0){
perror("stat");
return -1;
}
char Per[10]=" ";
char *pstr=NULL;
char type=0;
//文件类型和权限
//printf("mode : %o\n",buf.st_mode);
type = get_FileType(buf.st_mode);
putchar(type);
//get_FilePermission(buf.st_mode,Per);
//printf("%s ",Per);
pstr = get_FilePermission(buf.st_mode,Per);
printf("%s ",pstr);
//printf("%s ",get_FilePermission(buf.st_mode,Per));
//文件硬链接数
printf("%ld ",buf.st_nlink);
//文件所属用户
char pwnm[32]="";
pstr = get_Filepwname(buf.st_uid,pwnm);
//printf("%s ",pwnm);
printf("%s ",pstr);
//printf("uid : %d\n",buf.st_uid);
//文件所属组用户
char grnm[32]="";
pstr = get_Groupname(buf.st_gid,grnm);
//printf("%s ",grnm);
printf("%s ",pstr);
//printf("gid : %d\n",buf.st_gid);
//文件大小
printf("%5ld ",buf.st_size);
//文件时间
get_calendar(buf.st_ctime);
//printf("time : %ld\n",buf.st_ctime);
//文件名
printf("%s\n",argv[1]);
return 0;
}