UNIX-LINUX编程实践教程-第三章-实例代码注解-ls2

一 问题

  对ls1的功能进行扩展,以达到类似ll命令的功能。

二 分析

  在ls1中,我们利用readdir()函数和dirent结构体来获得目标文件夹内的文件名(dirent->d_name)。
  现在我们借助函数stat()和结构体stat以及上面得到的文件名来获得该目录内文件的详细信息(参看后面的“相关函数与结构体”部分)。

三 实现

1 头文件

#include<stdio.h>
#include<sys/types.h>
#include<dirent.h>
#include<sys/stat.h>
#include<string.h>

2 相关函数声明

void do_ls(char dirname[]);
void dostat(char *filename);
void show_file_info(char *filename,struct stat *info_p);
void mode_to_letters(int mode,char str[]);
char *uid_to_name(uid_t uid);
char *gid_to_name(gid_t gid);

3 主函数

获得目录的路径,并将该路径传递给do_ls()函数

main(int ac,char *av[])
{if(ac == 1){do_ls(".");}else{while(--ac){printf("%s:\n",*++av);/* 传递目录路径到do_ls函数 */do_ls(*av);}}
}

4 do_ls()函数

结合opendir()函数和readdir()函数,通过目录的路径获得该目录内各文件或文件夹的名称,并将该名称传递给dostat()函数

void do_ls(char dirname[])
{DIR *dir_ptr;struct dirent *direntp;/* 使用opendir()函数“打开”目录,返回指向该目录的指针 */if((dir_ptr = opendir(dirname))==NULL){fprintf(stderr,"ls2:cannot open %s\n",dirname);}else{/* 使用readdir()函数读取指针指向的目录,获得dirent结构体 */while((direntp = readdir(dir_ptr))!=NULL){/* 通过dirent结构体获得文件名,并将文件名传递给dostat()函数 */dostat(direntp->d_name);}closedir(dir_ptr);}
}

5 dostat()函数

使用stat()函数,通过文件或文件夹的名称获得保存了该文件信息的stat结构体,将该结构体传递给show_file_info()函数

void dostat(char *filename)
{struct stat info;/* 使用stat()函数,通过文件名获得stat结构体info */if(stat(filename,&info) == -1){perror(filename);}else{/* 将stat结构体传递给show_file_info()函数 */show_file_info(filename,&info);}
}

6 show_file_info()函数

将stat结构体中的各项参数分别解析并输出到标准输出

void show_file_info(char *filename,struct stat *info_p)
{/* 各解析函数声明 */char *uid_to_name(),*ctime(),*gid_to_name(),*filemode();void mode_to_letters();char modestr[11];/* 解析并输出文件的mode信息 */mode_to_letters(info_p->st_mode,modestr);printf("%s",modestr);/* 文件连接数 */printf("%4d",(int)info_p->st_nlink);/* 通过uid获得对应的用户名 */printf("%-8s",uid_to_name(info_p->st_uid));/* 通过gid获得对应的组名 */printf("%-8s",gid_to_name(info_p->st_gid));/* 文件大小 */printf("%8ld",(long)info_p->st_size);/* 最近一次修改时间 */printf("%.12s",4+ctime(&info_p->st_mtime));/* 文件名 */printf("%s\n",filename);
}

 7 mode_to_letters()函数

将传递进来的mode参数解析成string格式

void mode_to_letters(int mode,char str[])
{strcpy(str,"----------");if(S_ISDIR(mode)) str[0] = 'd';if(S_ISCHR(mode)) str[0] = 'c';if(S_ISBLK(mode)) str[0] = 'b';if(mode&S_IRUSR) str[1] = 'r';if(mode&S_IWUSR) str[2] = 'w';if(mode&S_IXUSR) str[3] = 'x';if(mode&S_IRGRP) str[4] = 'r';if(mode&S_IWGRP) str[5] = 'w';if(mode&S_IXGRP) str[6] = 'x';if(mode&S_IROTH) str[7] = 'r';if(mode&S_IWOTH) str[8] = 'w';if(mode&S_IXOTH) str[9] = 'x';
}

其中S_ISDIR、S_ISCHR、S_ISBLK等是宏,定义如下所示:

#define S_ISFIFO(m) (((m)(0170000)) == (0010000))
#define S_ISDIR(m) (((m)(0170000)) == (0040000))
#define S_ISCHR(m) (((m)(0170000)) == (0020000))
#define S_ISBLK(m) (((m)(0170000)) == (0060000))
#define S_ISREG(m) (((m)(0170000)) == (0100000))

8 uid_to_name()函数

通过用户的uid,利用getpwuid()函数,将uid转换为用户名

#include<pwd.h>
char *uid_to_name(uid_t uid)
{struct passwd *getpwuid(),*pw_ptr;static char numstr[10];if((pw_ptr = getpwuid(uid))==NULL){sprintf(numstr,"%d",uid);return number;}else{return pw_ptr->pw_name;}
}

9 gid_to_name()函数

通过用户的gid,利用getgrgid()函数,将gid转换为组名

#include<grp.h>
char *gid_to_name(gid_t gid)
{struct group *getgrgid(),*grp_ptr;static char numstr[10];if((grp_ptr = getgrgid(gid))==NULL){sprintf(numstr,"%d",gid);return numstr;}else{return grp_ptr->gr_name;}
}

 

相关函数与结构体

1 stat()函数
通过文件名获取文件信息,并保存在stat结构体中
头文件:#include <sys/stat.h>  #include <unistd.h>
函数原型 int stat(const char *file_name, struct stat *buf)
参数    file_name 指向文件名的指针
      buf 指向stat结构体的指针
返回值   0 执行成功
      -1 执行失败,错误代码存于ermo中

2 stat结构体
头文件:#include<sys/stat.h>
struct stat
{
  mode_t st_mode; //文件对应的模式,文件,目录等
  ino_t st_ino; //i-node节点号
  dev_t st_dev; //设备号码
  dev_t st_rdev; //特殊设备号码
  nlink_t st_nlink; //文件的连接数
  uid_t st_uid; //文件所有者
  gid_t st_gid; //文件所有者对应的组
  off_t st_size; //普通文件,对应的文件字节数
  time_t st_atime; //文件最后被访问的时间
  time_t st_mtime; //文件内容最后被修改的时间
  time_t st_ctime; //文件状态(属性)改变时间
  blksize_t st_blksize; //文件内容对应的块大小
  blkcnt_t st_blocks; //文件内容对应的块数量
}

3 ctime()函数
把日期和时间转换为字符串
头文件:#include <cstdio>  #include <ctime>
函数原型 char *ctime(const time_t *time)
参数    time time_t格式的时间
返回值   char * 字符串格式的时间

4 getpwuid()函数
通过用户的uid查找用户的相关信息,并以passwd结构体返回其数据
头文件:#include <sys/types.h>  #include <pwd.h>
函数原型 struct passwd *getpwuid(uid_t uid)
参数    uid 用户的uid
返回值   passwd结构体 uid对应的用户信息
      空指针 出错

5 passwd结构体
struct passwd
{
  char * pw_name; /* Username, POSIX.1 */
  char * pw_passwd; /* Password */
  __uid_t pw_uid; /* User ID, POSIX.1 */
  __gid_t pw_gid; /* Group ID, POSIX.1 */
  char * pw_gecos; /* Real Name or Comment field */
  char * pw_dir; /* Home directory, POSIX.1 */
  char * pw_shell; /* Shell Program, POSIX.1 */
  char *pw_class;
  time_t pw_change;
  time_t pw_expire;
}

6 getgrgid()函数
通过gid,找到该组的相关信息,并以group结构体返回其信息
头文件:#include<grp.h>  #include<sys/types.h>
函数原型 strcut group * getgrgid(gid_t gid)
参数    gid
返回值   group结构体 正常
      NULL 无数据或发生错误

7 group结构体
struct group
{
  char *gr_name; /*组名称*/
  char *gr_passwd; /* 组密码*/
  gid_t gr_gid; /*组识别码*/
  char **gr_mem; /*组成员账号*/
}

 

转载于:https://www.cnblogs.com/cation/archive/2013/01/29/2875311.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ajax入门篇

什么是ajax AJAX即“Asynchronous JavaScript and XML”&#xff08;异步的JavaScript与XML技术&#xff09;&#xff0c;指的是一套综合了多项技术的浏览器端网页开发技术。Ajax的概念由杰西詹姆士贾瑞特所提出[1]。 传统的Web应用允许用户端填写表单&#xff08;form&#…

BJRangeSliderWithProgress

2019独角兽企业重金招聘Python工程师标准>>> BJRangeSliderWithProgress 是一个带范围选择的进度条&#xff0c;我用它来做录音的进度指示&#xff0c;并可在选择的范围内进行回放。 转载:http://www.adobex.com/ios/source/details/00000865.htm 转载于:https://my…

servlet+JQuery ajax以json的形式的验证表单小实例

JQuery $.ajax() $.ajax({type: POST, //请求方式 一般是get&#xff0c;posturl: url , // 这是必需的&#xff0c;规定把请求发送到哪个 URLdata: data , //这个是可选。映射或字符串值。规定连同请求发送到服务器的数据。java中用request.getPara…

JSONObject与GSON的一些常用的方法的使用

通过学习ajax然后接触了Json最后通过json接触到了JSONObject和Google的GSON&#xff0c;下面来一起看看JSONObject和GSON吧。 先附上依赖 //JSONObject依赖<dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId>&…

tomcat 启用NIO

从Tomcat6.0以后, Java开发者很容易就可以是用NIO的技术来提升tomcat的并发处理能力。 <Connector port"8080" protocol"HTTP/1.1"connectionTimeout"20000"redirectPort"8443" /> 修改成&#xff1a; <Connector port"…

Mybatis(2)---多表查询

首先数据库表展示 User表 Role角色表 关联User表与Role表关系的user_role表 因为是要串联关系所以需要设置外键&#xff0c;以下是外键展示 工程目录展示 pom.xml依赖配置 <dependencies><dependency><groupId>junit</groupId><artifactId>…

ORA-29702:error occurred in Cluster Group Service operation错误解决

ORA-29702:error occurred in Cluster Group Service operation错误解决作者: djb1008(http://djb1008.itpub.net)发表于: 2011.05.10 15:43分类: Oracle 出处: http://djb1008.itpub.net/post/42280/517654--------------------------------------------------------------- 一…

JavaScript复习使用定时器的简易式诸葛大力轮播图

先上效果图 很简单的代码 先创建个文件夹保存成果的照片&#xff0c;然后通过更改src来用定时器循环这些照片 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"…

搜索分布式

http://blog.sina.com.cn/s/blog_539d361e0100xcy9.html http://stackoverflow.com/questions/6923071/lucene-is-it-the-right-answer-for-huge-index http://www.hpl.hp.com/techreports/2008/HPL-2008-64.html http://www.gossamer-threads.com/lists/lucene/general/58087

复习---使用基础语法实现栈及迭代

上图是最最基本的结构&#xff0c;这次我采用数组实现栈。使用数组实现栈&#xff0c;由于java的数组是固定长度的。所以我需要写一个增加长度的方法。然后就是迭代的问题了。使用数组实现栈的话&#xff0c;我们需要写一个迭代器。不过这个迭代器非常容易实现&#xff0c;只需…

同一个闭区间上有界变差函数的和与积都是有界变差函数

设$f,g$是$[a,b]$上的[有界变差函数],则$fg$也是$[a,b]$上的有界变差函数. 证明&#xff1a;设$P\{x_0,\cdots,x_n\}$是对$[a,b]$的任意分割.由于$f$是$[a,b]$上的有界变差函数&#xff0c;因此$$\sum_{i0}^{n-1}|f(x_{i1})-f(x_i)|<M_1$$且$$\sum_{i0}^{n-1}|g(x_{i1})-g(x…

复习----使用链表实现栈(后进先出)及迭代

使用链表进行模拟栈比用数组好用&#xff0c;考虑的要素也少还方便。 链表结构 private class Node{//链表结构Item item;Node next;}迭代器 private class Iterator implements java.util.Iterator<Item>{//迭代器private Node pfirst;Overridepublic boolean hasNex…

复习----使用链表实现队列(先进先出)及迭代

实现队列比实现栈的会多一点复杂&#xff0c;需要两个标记&#xff0c;first表示队头&#xff0c;last表示队尾。 链表结构 private class Node{Item item;Node next;}迭代器 与实现栈的迭代器一模一样 private class Iterator implements java.util.Iterator<Item>{p…

感冒不吃药

感冒药既治不好感冒也不能加速痊愈&#xff0c;只是缓解症状而已 有两百多种不同的病毒都可以引起普通感冒。还有一种感冒叫流感&#xff0c;比起普通感冒来更严重&#xff0c;可能会多高热、恶心等症状。不过流感是由特定的流感病毒引发&#xff0c;可以通过打疫苗来预防。不管…

复习--linux目录及文件操作

文件及目录的一些操作 你可以使用 man [命令]来查看各个命令的使用文档&#xff0c;如 &#xff1a;man mv 目录查看 目录查看 ls -[alh] [文件或目录名称] 不加 [文件或目录名称]的话默认是当前目录路径 绝对路径 从根目录开始写起&#xff0c;用 /表示根目录 相对路径 ./表示…

RedHat Enterprise AS4安装步骤

//因RDMS使用新版本CentOS6.2 有问题 &#xff0c; 没办法只有装低版本操作系统 &#xff01; 概述 Redhat公司的Enterprise Linux AS系列 &#xff08;以下简称AS系列&#xff09;&#xff0c;其中Fedora Core 是符合GPL协议的免费版本&#xff0c;使用范围广泛。AS是高性能的…

贪心---leetcode-376摆动序列

题目 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为摆动序列。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。少于两个元素的序列也是摆动序列。 例如&#xff0c; [1,7,4,9,2,5] 是一个摆动序列&#xff0c;因为差值 (6,-3,…

[转]我们为什么需要工作流

本文转自&#xff1a;http://www.cnblogs.com/foundation/archive/2009/01/12/1374163.html 这是我的"基于WF设计业务流程平台"的题外篇 以下是这系列的文章列表,写的很痛苦,但我会继续写下去 基于WF设计业务流程平台-架构 基于WF设计业务流程平台-权限体系 基于WF设…

贪心---移掉K位数字

题目 给定一个以字符串表示的非负整数 num&#xff0c;移除这个数中的 k 位数字&#xff0c;使得剩下的数字最小。 注意: num 的长度小于 10002 且 ≥ k。num 不会包含任何前导零。 示例 1 : 输入: num “1432219”, k 3 输出: “1219” 解释: 移除掉三个数字 4, 3, 和 2 形…

应用层——使用 Socket 通信实现 FTP 客户端程序

转自&#xff1a;http://blog.csdn.net/yixijide/article/details/8280263 简介&#xff1a; FTP 客户端如 FlashFXP&#xff0c;File Zilla 被广泛应用&#xff0c;原理上都是用底层的 Socket 来实现。FTP 客户端与服务器端进行数据交换必须建立两个套接字&#xff0c;一个作为…