2017-2018-1 20155205 实现mypwd

课堂总结

根据上课对ls -l功能的实现,我总结了实现一个linux命令需要的步骤:

  1. 使用man -k xx | grep xx查看帮助文档,这里需要查看相关函数的参数、返回值和头文件,同时也要看一下SEE ALSO里与我们查找的功能相关的其他函数。
  2. 借鉴实现其他命令的思路,比如实现myod时,我们要opendir、readdir和closedir,其实每个命令都需要执行这两步,我们就可以按这个思路来写其他的命令。

mypwd的实现

  1. 查看pwd帮助文档,看到一个getcwd,又查看了一下getcwd帮助文档发现这个函数可以直接获取当前路径!

参考getcwd()函数的用法的代码可以实现pwd的功能。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(void)
{
char *path = NULL;
path = getcwd(NULL,0);
puts(path);
free(path);
return 0;
}

2.按照老师上课的教学内容,我们还可以用stat来实现pwd。

首先在学习过程中,我们知道了上一级“.”和上上级“..”的结点信息的关系。

先看一下stat中的结构体,可以看到ino_t是存储结点数的,所以我们编程序要用到它。

struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is NOT defined */
dev_t st_dev; /* device inode resides on */
ino_t st_ino; /* inode's number */
mode_t st_mode; /* inode protection mode */
nlink_t st_nlink; /* number of hard links to the file */
uid_t st_uid; /* user-id of owner */
gid_t st_gid; /* group-id of owner */
dev_t st_rdev; /* device type, for special file inode */
struct timespec st_atimespec; /* time of last access */
struct timespec st_mtimespec; /* time of last data modification */
struct timespec st_ctimespec; /* time of last file status change */
off_t st_size; /* file size, in bytes */
quad_t st_blocks; /* blocks allocated for file */
u_long st_blksize;/* optimal file sys I/O ops blocksize */
u_long st_flags; /* user defined flags for file */
u_long st_gen; /* file generation number */
};

上网查了相关资料后,发现我们还需要掌握一个DIR结构体:

struct __dirstream
{
void *__fd; // `struct hurd_fd' pointer for descriptor.
char *__data; // Directory block.
int __entry_data; // Entry number `__data' corresponds to.
char *__ptr; // Current pointer into the block.
int __entry_ptr; // Entry number `__ptr' corresponds to.
size_t __allocation;// Space allocated for the block.
size_t __size; // Total valid data in the block.
__libc_lock_define (, __lock) // Mutex lock for this structure.
};
typedef struct __dirstream DIR;

DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息。函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:

struct dirent *readdir(DIR *dp);   

void rewinddir(DIR *dp);   

int closedir(DIR *dp);   

long telldir(DIR *dp);   

void seekdir(DIR *dp,long loc);

接着是dirent结构体,首先我们要弄清楚目录文件(directory file)的概念:这种文件包含了其他文件的名字以及指向与这些文件有关的信息的指针。从定义能够看出,dirent不仅仅指向目录,还指向目录中的具体文件,readdir函数同样也读取目录下的文件,这就是证据。以下为dirent结构体的定义:

struct dirent
{
  long d_ino; /* inode number 索引节点号 */
  
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
  
unsigned short d_reclen; /* length of this d_name 文件名长 */
  
unsigned char d_type; /* the type of d_name 文件类型 */
  
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}
  • 伪代码
获取当前文件名和结点数;
if("."与".."结点数不相等)

打印当前文件名;
cd上一级;

  • 测试代码
#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<dirent.h>
#include<stdlib.h>
#include<string.h> #define SIZE 128 ino_t getinode(char *dirname); //获取文件名称
void getwork(ino_t inode_num);
void dirname(ino_t inode_num, char *buf, int buflen); int main(void)
{
getwork(getinode("."));
printf("\n");
return 0; } ino_t getinode(char *dirname) //通过stat得到文件名
{
struct stat name;
if (stat(dirname, &name) == -1)
{
perror("dirname");
exit(1);
} return name.st_ino;
} void getwork(ino_t inode_num)
{
ino_t parent_inode;
char buf[SIZE];
if (getinode("..") != inode_num)
{
chdir(".."); //到达..文件
dirname(inode_num, buf, SIZE);
parent_inode = getinode(".");
getwork(parent_inode); //此处通过递归来不断到达上一级
printf("/%s", buf);
}
} void dirname(ino_t inode_num, char *buf,int buflen) //
{
DIR *dir_ptr;
struct dirent *dirt;
if ((dir_ptr = opendir(".")) == NULL)
{
perror(".");
exit(1);
} while ((dirt = readdir(dir_ptr)) != NULL)
{
if (dirt->d_ino == inode_num)
{
strncpy(buf, dirt->d_name, buflen);
buf[strlen(buf)] = '\0';
closedir(dir_ptr);
return ;
}
} exit(1);
}
  • 测试结果

2017-2018-1 20155205 实现mypwd的更多相关文章

  1. MyEclips 2017/2018 (mac 版)安装与破解

    MyEclips 2017/2018 (mac 版)安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEclips ...

  2. MyEclipse 2017/2018 安装与破解 图文教程

    SSM 框架-02-MyEclipse 2017/2018 安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEc ...

  3. </2017><2018>

    >>> Blog 随笔原始文档及源代码 -> github: https://github.com/StackLike/Python_Note >>> 统计信 ...

  4. 我的2017&2018

    最近项目进入验收阶段,所以上班没那么忙碌了,但是怎么说呢,我可能天生是闲不住的主,觉得浑身不自在(我这样的人是不是特别不会享福),此处应该有个笑脸哈. 翻看了博客园好几个大牛写的技术文章,感慨大牛不愧 ...

  5. [2017 - 2018 ACL] 对话系统论文研究点整理

    (论文编号及摘要见 [2017 ACL] 对话系统. [2018 ACL Long] 对话系统. 论文标题[]中最后的数字表示截止2019.1.21 google被引次数) 1. Domain Ada ...

  6. CorelDRAW X7 X8 2017 2018是什么关系?

    从CorelDRAW 2017版本开始我们叫习惯了的X几系列的CorelDRAW毅然决然的就换了称呼,所以有时候很多朋友对于软件版本,经常会傻傻分不清,还有人认为X8版本比2017版本高,究竟为什么会 ...

  7. JetBrains 2017/2018全系列产品激活工具

    可谓是工欲善其事,必先利其器,相信作为优秀开发工程师的你都想拥有一套快捷高效的编码工具,而JetBrains这家公司的产品,不管是那种编程语言,其开发工具确实让开发者们着迷,JetBrains的产品博 ...

  8. 【LOJ】#2349. 「JOI 2017/2018 决赛」团子制作

    题解 有意思的一个dp,我们对G计数,发现如果不在同一条对角线上的G肯定不会互相影响,所以我们对于每一条对角线dp dp的方式是枚举这个G以什么方式放,横着还是竖着,还是不放 代码 #include ...

  9. 【LOJ】#2350. 「JOI 2017/2018 决赛」月票购买

    题解 首先求一个最短路图出来,最短路图就是这条边在最短路上就保留,否则就不保留,注意最短路图是一个有向图,一条边被保留的条件是 dis(S,u) + val(u,v) = dis(v,T)我们需要求两 ...

随机推荐

  1. HttpServletRequest对象

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...

  2. JS对select动态添加options操作(主流浏览器兼容)

    之前项目中,遇到一个表单提交的页面,里面有多级下拉框联动的复杂逻辑,因此当时在做的过程中也是学到了不少容易出现问题的地方,下面就整理下当时遇到的一些关于下拉框的操作,并指出其中的一些注意点和坑: 有如 ...

  3. Python机器学习中文版

    Python机器学习简介 第一章 让计算机从数据中学习 将数据转化为知识 三类机器学习算法 第二章 训练机器学习分类算法 透过人工神经元一窥早期机器学习历史 使用Python实现感知机算法 基于Iri ...

  4. manacher模板(manacher)

    洛谷题目传送门 写完有一段时间了,发现板子忘记存在了这里...... 算法简述 一种字符串算法,\(O(n)\)高效求出以每个字符为对称中心的最长回文串长度. 然后,就可以进一步求出全串中最长回文串的 ...

  5. 【2016北京集训测试赛】azelso

    [吐槽] 首先当然是要orzyww啦 以及orzyxq奇妙顺推很强qwq 嗯..怎么说呢虽然说之前零零散散做了一些概d的题目但是总感觉好像并没有弄得比较明白啊..(我的妈果然蒟蒻) 这题的话可以说是难 ...

  6. html onclick时间传字符串参数

    经常忘记拼html中onclick事件传字符串引号的问题,所以今天记一下! 简单一句话 外面是"",里面就是'',外边是'',里边就是"".   示例: var ...

  7. 简单总结下 cookie、session

      Cookies:     定义:cookie 中文意思是"小甜饼",但是,在互联网中它跟食品没有半毛钱关系,它主要是由web服务器应用程序创建,在客户端计算机中保存,问题来了, ...

  8. Problem : (1.2.1) Text Reverse

    #include<iostream> using namespace std; void main() { char arr[1000]; int a,n; int s,t; cin> ...

  9. Unity性能优化的N种武器

    贴图: l  控制贴图大小,尽量不要超过 1024 x1024: l  尽量使用2的n次幂大小的贴图,否则GfxDriver里会有2份贴图: l  尽量使用压缩格式减小贴图大小: l  若干种贴图合并 ...

  10. 邮箱&&密码验证-原理

    原理版: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...