免费软件下载官方网站,移动网站的开发流程图,自己能注册网站吗,陕西建设机械官方网站关键函数的功能及说明
1.void display_attribute(struct stat buf,char *name)
函数功能#xff1a;打印文件名为name的文件信息#xff0c;如 含义分别为#xff1a;文件的类型和访问权限#xff0c;文件的链接数#xff0c;文件的所有者#xff0c;文件所有者所属的组…
关键函数的功能及说明
1.void display_attribute(struct stat buf,char *name)
函数功能打印文件名为name的文件信息如 含义分别为文件的类型和访问权限文件的链接数文件的所有者文件所有者所属的组文件大小文件创建的时间
2.void dispaly_single(char *name)
函数功能输出文件的文件名如果命令中没有-l选项则输出文件名时要保证上下对齐如 3.void display(int flag,char *pathname)
函数功能根据命令行参数存放在flag中和完整路径名存放在pathname中显示目标文件参数flag可以取以下值或者它们的组合 4.void diaplay_dir(int flag_param,char *path)
函数功能为显示某个目录下的文件做准备参数flag_param用于在调用display函数时作为其参数flag的实参path是要显示的目录
函数流程 准备工作代码
#includecstdlib
#includecstring
#include cstdio
#includectime
#includesys/types.h
#includesys/stat.h
#includefcntl.h
#includeunistd.h
#includecerrno
#includedirent.h
#includelinux/limits.h
#includepwd.h
#includegrp.h
#includealgorithm
using namespace std;#define PARAM_NONE 0//无参数
#define PARAM_A 1//-a 显示所有文件
#define PARAM_L 2 //-l 一行只显示一个文件的详细信息
#define MAXROWLEN 80 //一行显示的最多字符数int g_leave_lenMAXROWLEN;//一行剩余长度用于输出对齐
int g_maxlen; //存放某目录下最长文件名的长度
//自定义错误处理函数
void my_err(const char *err_string,int line){fprintf(stderr,line:%d ,line);perror(err_string);exit(1);
}
int cmp(const void *a, const void *b)
{return ((char *)a)[0] - ((char *)b)[0];
}
顺便了解 pwd.h 和 grp.h 是两个C语言标准库头文件用于处理用户和组的信息通常用于UNIX和类UNIX系统。 pwd.h - Password Database: 该头文件定义了与用户账户信息相关的结构和函数。主要包括获取和处理用户账户信息的功能例如用户名、用户IDUID、组IDGID、用户家目录等。一些常见的函数和结构体包括 getpwnam通过用户名获取用户信息。getpwuid通过用户ID获取用户信息。struct passwd用于存储用户账户信息的结构体。 grp.h - Group Database: 该头文件定义了与用户组信息相关的结构和函数。主要包括获取和处理用户组信息的功能例如组名、组IDGID、组成员等。一些常见的函数和结构体包括 struct group用于存储用户组信息的结构体。getgrgid通过组ID获取组信息。getgrnam通过组名获取组信息。 如果你不清楚函数代码实在干嘛可以看一下上面的运行结果这样才知道到底要输出什么
display_attribute代码
//获取文件属性并打印
void display_attribute(struct stat buf,char *name){char buf_time[32];struct passwd *psd;//从该结构体中获取文件所有者的用户名struct group *grp;//从该结构体中获取文件所有者所属组的组名//获取并打印文件类型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_ISSOCK(buf.st_mode))printf(s);//套接字文件else if(S_ISFIFO(buf.st_mode))printf(f);//FIFO文件//获取并打印文件所有者的权限if(buf.st_modeS_IRUSR)printf(r);else printf(-);if(buf.st_modeS_IWUSR)printf(w);else printf(-);if(buf.st_modeS_IXUSR)printf(x);else printf(-);//获取并打印与文件所有者同组的用户对该文件的操作权限if(buf.st_modeS_IRGRP)printf(r);else printf(-);if(buf.st_modeS_IWGRP)printf(w);else printf(-);if(buf.st_modeS_IXGRP)printf(x);else printf(-);//获取并打印其他用户对该文件的操作权限if(buf.st_modeS_IROTH)printf(r);else printf(-);if(buf.st_modeS_IWOTH)printf(w);else printf(-);if(buf.st_modeS_IXOTH)printf(x);else printf(-);printf( );//根据uid与gid获取文件所有者的用户名与组名psdgetpwuid(buf.st_uid);grpgetgrgid(buf.st_gid);printf(%4d,buf.st_nlink);//打印文件的链接数printf(%-8s,psd-pw_name);printf(%-8s,grp-gr_name);printf(%6d,buf.st_size);//打印文件的大小strcpy(buf_time,ctime(buf.st_mtime));buf_time[strlen(buf_time)-1]\0;//去掉换行符printf( %s,buf_time);//打印文件的时间信息
}
struct stat这个结构体在《Linux C编程实战》笔记文件属性操作函数-CSDN博客 这里放过具体的信息可以看到主要是从st_mode获取信息 S_ISLNK 是一个宏macro通常用于检查给定文件的模式是否表示一个符号链接Symbolic Link。这个宏在UNIX和类UNIX系统的系统编程中很常见特别是在处理文件和目录时。 S_ISLNK 的定义通常在 sys/stat.h 头文件中这个头文件包含了有关文件状态file status的相关宏和结构体定义。它的典型用法是与 st_mode 结构成员一起使用 其他的宏都是类似的作用用来检查文件具体是那种类型的。 buf.st_mode S_IRGRP 是一个位运算的操作用于检查给定文件的权限位 S_IRGRP之类的文件权限的宏在 《Linux C编程实战》笔记文件读写-CSDN博客 有具体解释过通过这个操作可以得知文件的具体权限 用 getpwuid 和 getgrgid 函数来获取文件或目录的所有者user和所属组group的相关信息。这两个函数通常与文件状态结构 struct stat 中的 st_uid用户ID和 st_gid组ID成员一起使用。 #include pwd.hstruct passwd *getpwuid(uid_t uid);
#include grp.hstruct group *getgrgid(gid_t gid);struct passwd {char *pw_name; // 用户名char *pw_passwd; // 加密后的密码uid_t pw_uid; // 用户IDgid_t pw_gid; // 主组IDchar *pw_gecos; // 用户的真实姓名等描述信息char *pw_dir; // 用户的主目录char *pw_shell; // 用户的登录shell
};struct group {char *gr_name; // 组名char *gr_passwd; // 加密后的密码在 /etc/gshadow 中gid_t gr_gid; // 组IDchar **gr_mem; // 用户名的数组表示属于这个组的成员
};ctime的具体用法也在 《Linux C编程实战》笔记文件属性操作函数-CSDN博客 有提到 %-8s的格式时它包含两个部分-8 是一个标志flag表示左对齐输出而 %s 表示将一个字符串插入到该位置。 %s插入一个字符串。-8左对齐并占用最少8个字符的宽度。如果字符串长度不足8个字符将用空格在右侧填充。 dispaly_single代码
//在没有使用-l选项时打印一个文件名打印时上下对齐
void display_single(char *name){int i,len;//如果本行不足以打印一个文件名则换行if(g_leave_leng_maxlen){printf(\n);g_leave_lenMAXROWLEN;}lenstrlen(name);leng_maxlen-len;printf(%-s,name);//为了保持对齐需要填充空格来实现和最长文件名占位相同for(i0;ilen;i){printf( );}printf( );g_leave_len-(g_maxlen2);//改行剩下的长度减去最长文件名加两个空格的长度
}
这里主要是格式控制在准备代码里有每个变量具体的含义每次输出主要是更新g_leave_len display代码
/*
* 根据命令行参数和完整路径名显示目标文件
* 参数flag命令行参数
* 参数pathname包含了文件名的路径名
*/
void display(int flag,char *pathname){int i,j;struct stat buf;char name[NAME_MAX1];//从路径中解析出文件名其实就是最后一个/后面的字符串了//书中代码是这么来获得的感觉应该有更好的方法C语言好像没有split函数多少会麻烦一些for(i0,j0;istrlen(pathname);i){if(pathname[i]/){j0;continue;}name[j]pathname[i];}name[j]\0;//用lstat而不是stat以方便解析链接文件if(lstat(pathname,buf)-1)my_err(stat,__LINE__);switch (flag){case PARAM_NONE://没有选项if(name[0]!.){//隐藏的.目录文件就忽略display_single(name);}break;case PARAM_A:display_single(name);break;case PARAM_L:if(name[0]!.){display_attribute(buf,name);//详细信息printf( %s-\n,name);//最后打印文件名}break;case PARAM_APARAM_L:display_attribute(buf,name);printf( %-s\n,name);break;default:break;}
}
NAME_MAX在《Linux C编程实战》笔记目录操作-CSDN博客
lstat在《Linux C编程实战》笔记文件属性操作函数-CSDN博客 display_dir代码
void display_dir(int flag_param,char *path){DIR *dir;struct dirent *ptr;int count0;char filenames[256][PATH_MAX1],temp[PATH_MAX1];//获取该目录下文件总数和最长的文件名diropendir(path);if(dirnullptr)my_err(opendir,__LINE__);while((ptrreaddir(dir))!nullptr){if(g_maxlenstrlen(ptr-d_name))g_maxlenstrlen(ptr-d_name);//更新最长的文件名长度count;}closedir(dir);if (count256){my_err(too maney files under this dir,__LINE__);}int i,j,lenstrlen(path);//获取该目录下所有的文件名diropendir(path);for(i0;icount;i){ptrreaddir(dir);if(ptrnullptr)my_err(readdir,__LINE__);strncpy(filenames[i],path,len);filenames[i][len]\0;strcat(filenames[i],ptr-d_name);//把目录名称和目录下的文件名拼一起filenames[i][lenstrlen(ptr-d_name)]\0;}//给文件名排序//源代码里用的是冒泡排序不是重点用一下stl算了偷个懒qsort(filenames,count,sizeof(filenames[0]),cmp);for(i0;icount;i)display(flag_param,filenames[i]);closedir(dir);//如果命令行中没有-l选项打印一个换行符if((flag_paramPARAM_L)0)printf(\n);
}
打开目录和遍历目录的操作我已经演示过了了《Linux C编程实战》笔记目录操作-CSDN博客 main函数代码
int main(int argc,char **argv){int i,j,k,num;char path[PATH_MAX1];char param[32];//保存命令行参数目标文件名和目录名不在这里int flag_paramPARAM_NONE;//参数种类struct stat buf;//命令行参数的解析分析 -l、-a、-al、-la选项j0;num0;for(i1;iargc;i){if(argv[i][0]-){//是一个命令for(k1;kstrlen(argv[i]);k,j){param[j]argv[i][k];//把命令的参数a或l都放到param数组里}num;//保存-的个数}}//j现在是param数组的长度for(int i0;ij;i){//遍历param数组看参数都是什么if(param[i]a){flag_param|PARAM_A;continue;}else if(param[i]l){flag_param|PARAM_L;continue;}else{//al以外的参数不支持printf(my_ls:invalid option -%c\n,param[i]);exit(1);}}param[j]\0;//如果没有输入文件名或目录则显示当前目录if((num1)argc){//这表示除了参数没有输入文件或目录strcpy(path,./);//path变成当前目录path[2]\0;display_dir(flag_param,path);//用显示目录的函数return 0;}//开始遍历文件或目录i1;do{//如果不是目标文件或目录解析下一个命令行参数if(argv[i][0]-){i;continue;}else{strcpy(path,argv[i]);//如果目标文件或目录不存在报错并退出if(stat(path,buf)-1)my_err(stat,__LINE__);if(S_ISDIR(buf.st_mode)){//argv[i]是一个目录//如果目录的最后一格字符不是/,就把/加上if(path[strlen(argv[i])-1]!/){path[strlen(argv[i])]/;path[strlen(argv[i])1]\0;}else path[strlen(argv[i])]\0;//也是调用显示目录的函数display_dir(flag_param,path);i;}else{//argv[i]是一个文件display(flag_param,path);i;}}} while (iargc);return 0;
}
这里说一下argc和argv不然可能搞不懂。
运行程序时如果啥都不跟直接./a.out这种的话argc默认为1argv[0]是程序名字如果后面带了参数比如这样
./a.out arg1 arg2 arg3那argc就是4argv[1],argv[2],argv[3]存的是参数的字符串
所以argv代码里都是从1开始因为argv[0]默认存的是程序名称。
编译运行一下 结果还是很完美的
一整个源码也在这方便直接抄了但是没有注释
#includecstdlib
#includecstring
#include cstdio
#includectime
#includesys/types.h
#includesys/stat.h
#includefcntl.h
#includeunistd.h
#includecerrno
#includedirent.h
#includelinux/limits.h
#includepwd.h
#includegrp.h
#includealgorithm
using namespace std;
#define PARAM_NONE 0
#define PARAM_A 1
#define PARAM_L 2
#define MAXROWLEN 80int g_leave_lenMAXROWLEN;
int g_maxlen;
//自定义错误处理函数
void my_err(const char *err_string,int line){fprintf(stderr,line:%d ,line);perror(err_string);exit(1);
}
int cmp(const void *a, const void *b)
{return ((char *)a)[0] - ((char *)b)[0];
}
void display_attribute(struct stat buf,char *name){char buf_time[32];struct passwd *psd;struct group *grp;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_ISSOCK(buf.st_mode))printf(s);else if(S_ISFIFO(buf.st_mode))printf(f);if(buf.st_modeS_IRUSR)printf(r);else printf(-);if(buf.st_modeS_IWUSR)printf(w);else printf(-);if(buf.st_modeS_IXUSR)printf(x);else printf(-);if(buf.st_modeS_IRGRP)printf(r);else printf(-);if(buf.st_modeS_IWGRP)printf(w);else printf(-);if(buf.st_modeS_IXGRP)printf(x);else printf(-);if(buf.st_modeS_IROTH)printf(r);else printf(-);if(buf.st_modeS_IWOTH)printf(w);else printf(-);if(buf.st_modeS_IXOTH)printf(x);else printf(-);printf( );psdgetpwuid(buf.st_uid);grpgetgrgid(buf.st_gid);printf(%4d,buf.st_nlink);printf(%-8s,psd-pw_name);printf(%-8s,grp-gr_name);printf(%6d,buf.st_size);strcpy(buf_time,ctime(buf.st_mtime));buf_time[strlen(buf_time)-1]\0;printf( %s,buf_time);
}void display_single(char *name){int i,len;if(g_leave_leng_maxlen){printf(\n);g_leave_lenMAXROWLEN;}lenstrlen(name);leng_maxlen-len;printf(%-s,name);for(i0;ilen;i){printf( );}printf( );g_leave_len-(g_maxlen2);
}
void display(int flag,char *pathname){int i,j;struct stat buf;char name[NAME_MAX1];for(i0,j0;istrlen(pathname);i){if(pathname[i]/){j0;continue;}name[j]pathname[i];}name[j]\0;if(lstat(pathname,buf)-1)my_err(stat,__LINE__);switch (flag){case PARAM_NONE:if(name[0]!.){display_single(name);}break;case PARAM_A:display_single(name);break;case PARAM_L:if(name[0]!.){display_attribute(buf,name);printf( %s-\n,name);}break;case PARAM_APARAM_L:display_attribute(buf,name);printf( %-s\n,name);break;default:break;}
}void display_dir(int flag_param,char *path){DIR *dir;struct dirent *ptr;int count0;char filenames[256][PATH_MAX1],temp[PATH_MAX1];diropendir(path);if(dirnullptr)my_err(opendir,__LINE__);while((ptrreaddir(dir))!nullptr){if(g_maxlenstrlen(ptr-d_name))g_maxlenstrlen(ptr-d_name);count;}closedir(dir);if (count256){my_err(too maney files under this dir,__LINE__);}int i,j,lenstrlen(path);diropendir(path);for(i0;icount;i){ptrreaddir(dir);if(ptrnullptr)my_err(readdir,__LINE__);strncpy(filenames[i],path,len);filenames[i][len]\0;strcat(filenames[i],ptr-d_name);filenames[i][lenstrlen(ptr-d_name)]\0;}qsort(filenames,count,sizeof(filenames[0]),cmp);for(i0;icount;i)display(flag_param,filenames[i]);closedir(dir);if((flag_paramPARAM_L)0)printf(\n);
}
int main(int argc,char **argv){int i,j,k,num;char path[PATH_MAX1];char param[32];int flag_paramPARAM_NONE;struct stat buf;j0;num0;for(i1;iargc;i){if(argv[i][0]-){for(k1;kstrlen(argv[i]);k,j){param[j]argv[i][k];}num;}}for(int i0;ij;i){if(param[i]a){flag_param|PARAM_A;continue;}else if(param[i]l){flag_param|PARAM_L;continue;}else{printf(my_ls:invalid option -%c\n,param[i]);exit(1);}}param[j]\0;if((num1)argc){strcpy(path,./);path[2]\0;display_dir(flag_param,path);return 0;}i1;do{if(argv[i][0]-){i;continue;}else{strcpy(path,argv[i]);if(stat(path,buf)-1)my_err(stat,__LINE__);if(S_ISDIR(buf.st_mode)){if(path[strlen(argv[i])-1]!/){path[strlen(argv[i])]/;path[strlen(argv[i])1]\0;}else path[strlen(argv[i])]\0;display_dir(flag_param,path);i;}else{display(flag_param,path);i;}}} while (iargc);return 0;
}