2017-2018-1 20155205 实现mypwd
2017-2018-1 20155205 实现mypwd
课堂总结
根据上课对ls -l功能的实现,我总结了实现一个linux命令需要的步骤:
- 使用
man -k xx | grep xx查看帮助文档,这里需要查看相关函数的参数、返回值和头文件,同时也要看一下SEE ALSO里与我们查找的功能相关的其他函数。 - 借鉴实现其他命令的思路,比如实现myod时,我们要opendir、readdir和closedir,其实每个命令都需要执行这两步,我们就可以按这个思路来写其他的命令。
mypwd的实现
- 查看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的更多相关文章
- MyEclips 2017/2018 (mac 版)安装与破解
MyEclips 2017/2018 (mac 版)安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEclips ...
- MyEclipse 2017/2018 安装与破解 图文教程
SSM 框架-02-MyEclipse 2017/2018 安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEc ...
- </2017><2018>
>>> Blog 随笔原始文档及源代码 -> github: https://github.com/StackLike/Python_Note >>> 统计信 ...
- 我的2017&2018
最近项目进入验收阶段,所以上班没那么忙碌了,但是怎么说呢,我可能天生是闲不住的主,觉得浑身不自在(我这样的人是不是特别不会享福),此处应该有个笑脸哈. 翻看了博客园好几个大牛写的技术文章,感慨大牛不愧 ...
- [2017 - 2018 ACL] 对话系统论文研究点整理
(论文编号及摘要见 [2017 ACL] 对话系统. [2018 ACL Long] 对话系统. 论文标题[]中最后的数字表示截止2019.1.21 google被引次数) 1. Domain Ada ...
- CorelDRAW X7 X8 2017 2018是什么关系?
从CorelDRAW 2017版本开始我们叫习惯了的X几系列的CorelDRAW毅然决然的就换了称呼,所以有时候很多朋友对于软件版本,经常会傻傻分不清,还有人认为X8版本比2017版本高,究竟为什么会 ...
- JetBrains 2017/2018全系列产品激活工具
可谓是工欲善其事,必先利其器,相信作为优秀开发工程师的你都想拥有一套快捷高效的编码工具,而JetBrains这家公司的产品,不管是那种编程语言,其开发工具确实让开发者们着迷,JetBrains的产品博 ...
- 【LOJ】#2349. 「JOI 2017/2018 决赛」团子制作
题解 有意思的一个dp,我们对G计数,发现如果不在同一条对角线上的G肯定不会互相影响,所以我们对于每一条对角线dp dp的方式是枚举这个G以什么方式放,横着还是竖着,还是不放 代码 #include ...
- 【LOJ】#2350. 「JOI 2017/2018 决赛」月票购买
题解 首先求一个最短路图出来,最短路图就是这条边在最短路上就保留,否则就不保留,注意最短路图是一个有向图,一条边被保留的条件是 dis(S,u) + val(u,v) = dis(v,T)我们需要求两 ...
随机推荐
- 新建.Net Core应用程序后引用项一直黄色感叹号怎么办?
我们在vs中创建.Net Core应用程序后,引用项可能出现黄色感叹号,正常情况下,这种黄色感叹号时能在项目创建成功之后迅速消失的,可也有些时候一直不消失,怎么办? 我们可以选中异常的项目,然后右键菜 ...
- 1.17学习jquery权威指南
1.ajax方面(东西比较杂,很多相关于.net挂钩的服务器端接触没有实际操作,全部放进来,或许以后当作demo使用) ¥(“body”).load("text.txt"); ...
- Spring Data(一)概念和仓库的定义
Spring Data(一)概念和仓库的定义 Spring Data的主要任务是为数据访问提供一个相似的.一致的.基于Spring的编程模型,同时又保留着下面各个数据存储的特征.它使得使用数据访问技术 ...
- 【BZOJ2440】完全平方数(二分答案,莫比乌斯反演)
[BZOJ2440]完全平方数(二分答案,莫比乌斯反演) 题面 BZOJ 题解 很显然,二分一个答案 考虑如何求小于等于这个数的非完全平方数倍数的个数 这个明显可以直接,莫比乌斯反演一下 然后这题就很 ...
- 【BZOJ3295】动态逆序对(线段树,树状数组)
[BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...
- 魔改版ss-panel v3前端配置文件
配置文件所在目录:网站根目录/config/.config.php <?php // ss-panel v3 配置 // // !!! 修改此key为随机字符串确保网站安全 !!! $Syste ...
- 论文笔记(7):Constrained Convolutional Neural Networks for Weakly Supervised Segmentation
UC Berkeley的Deepak Pathak 使用了一个具有图像级别标记的训练数据来做弱监督学习.训练数据中只给出图像中包含某种物体,但是没有其位置信息和所包含的像素信息.该文章的方法将imag ...
- Sqlite 梳理
前言 LZ最近失业,梳理下最近一个项目的 项目结构-供应链系统 接着上一篇博客 http://www.cnblogs.com/buruainiaaaa/p/6786527.html 上篇说到整套系统分 ...
- Golang的CSP很酷?其实.NET也可以轻松完成
说起Golang(后面统称为Go),就想到他的高并发特性,在深入一些就是 Goroutine.在大家被它优雅的语法和简洁的代码实现的高并发程序所折服时,其实C#/.NET也可以很容易的做到.今天我们来 ...
- 设计模式——工厂方法模式(C++实现)
#include <iostream> #include <string> using namespace std; class CProduct { public: ; }; ...