在Linux中实现打印目录程序遇到问题及解决
今日阅读Linux程序设计第四版时,书中给出了一段实例代码,功能为实现/home目录下各级目录结构,当然不一定非得是/home下目录才可以,任何一级目录都可以。

自己尝试在Ubuntu系统运行编译,实现效果如下:

自己对该程序各行代码进行一个解读分析,同时查阅各项资料:
首先定义打印目录的函数
void printdir(char *dir ,int depth)
char *dir代表DIR目录名,int depth设置当前目录打印后所占空格位置
接下来定义函数内需要的三项参数
DIR *dp; /*申请一个目录指针*/
struct dirent *entry;/*申请一个结构体指针,该结构体包含目录和文件信息*/
struct stat statbuf; /*申请一个结构体,该结构体用于之后各级目录内文件访问权限的判定*/
通过查阅资料:
该部分中DIR,dirent和stat经常相互配合和使用。
DIR结构体是一个目录流指针,用于完成各项目录操作
dirent则类比于一个一个接受DIR指针传来目录,并将这个目录进一步细分化,引导到stat当中的中间站
stat则储存着各项目录内具体的文件信息
三者是一种递进的关系
接下来对输入参数有效性进行判断
if((dp = opendir(dir)) == NULL){ /*函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针*/
fprintf(stderr,"cannot open directory: %s\n",dir);
return;
} /*如果无法打开该目录,则直接打印该层目录信息*/
chdir(dir); /*chdir(const char * path)用于把当前工作目录更改为参数路径指示目录*/
该部分主要完成从目录到目录指针,以及判定是否为目录的操作
DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针
最后进行打印目录操作:
while((entry = readdir(dp)) != NULL){
lstat(entry->d_name,&statbuf); /* 该步骤将相关文件路径名字对应的文件结构体放入stat结构中 */
if(S_ISDIR(statbuf.st_mode)){ /* S_ISDIR宏用于判断传入参数是否是一个目录 */
if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0)/*如果到达根目录或者路径名为.,则跳过去该部分*/
continue;
printf("%*s%s/\n",depth,"",entry->d_name);
/* 假如depth等于5,可类比为:printf("%5s%s/\n","",entry->d_name) 此处留出depth的空格来,随后写入目录对应的文件名,然后另起一行 */
printdir(entry->d_name,depth+4);
}
else printf("%*s%s\n",depth,"",entry->d_name);
}/*该部分用于逐级循环,自上而下读入目录,返回各级目录指针*/
chdir("..");
closedir(dp);
具体部分功能已经标注,另外说明:
printf("%*s%s/\n",depth,"",entry->d_name)
该函数中%*s的※号代表接受后面的一个int参数变量,假设当前depth等于5,则类比为printf("%5s%s/\n","",entry->d_name) ,意思是先空出5个空格来,再进行目录打印。
为什么需要这样子?
因为目录在没完成单个文件名打印后需要另起一行,但是级别更加靠近根节点目录理应更加靠前,反之需要靠后。

该部分采用了递归方法:
printf("%*s%s/\n",depth,"",entry->d_name);
/* 假如depth等于5,可类比为:printf("%5s%s/\n","",entry->d_name) 此处留出depth的空格来,随后写入目录对应的文件名,然后另起一行 */
printdir(entry->d_name,depth+4);
}
else printf("%*s%s\n",depth,"",entry->d_name);
}/*该部分用于逐级循环,自上而下读入目录,返回各级目录指针*/
所以在每一层可以保留自己所在层的需要空出来的depth具体值。
全部代码如下:
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
void printdir(char *dir ,int depth)
{
DIR *dp; /*申请一个目录指针*/
struct dirent *entry;/*申请一个结构体指针,该结构体包含目录和文件信息*/
struct stat statbuf; /*申请一个结构体,该结构体用于之后各级目录内文件访问权限的判定*/
if((dp = opendir(dir)) == NULL){ /*函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针*/
fprintf(stderr,"cannot open directory: %s\n",dir);
return;
} /*如果无法打开该目录,则直接打印该层目录信息*/
chdir(dir); /*chdir(const char * path)用于把当前工作目录更改为参数路径指示目录*/
while((entry = readdir(dp)) != NULL){
lstat(entry->d_name,&statbuf); /* 该步骤将相关文件路径名字对应的文件结构体放入stat结构中 */
if(S_ISDIR(statbuf.st_mode)){ /* S_ISDIR宏用于判断传入参数是否是一个目录 */
if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0)/*如果到达根目录或者路径名为.,则跳过去该部分*/
continue;
printf("%*s%s/\n",depth,"",entry->d_name);
/* 假如depth等于5,可类比为:printf("%5s%s/\n","",entry->d_name) 此处留出depth的空格来,随后写入目录对应的文件名,然后另起一行 */
printdir(entry->d_name,depth+4);
}
else printf("%*s%s\n",depth,"",entry->d_name);
}/*该部分用于逐级循环,自上而下读入目录,返回各级目录指针*/
chdir("..");
closedir(dp);
}
int main()
{
printf("Directory scan of /home:\n");
printdir("/home",0);
printf("done.\n");
exit(0);
}
在Linux中实现打印目录程序遇到问题及解决的更多相关文章
- 在Linux中运行Nancy应用程序
最近在研究如何将.NET应用程序移植到非Windows操作系统中运行,逐渐会写一些文章出来.目前还没有太深的研究,所以这些文章大多主要是记录我的一些实验. 这篇文章记录了我如何利用NancyFx编写一 ...
- [转]Linux中文件权限目录权限的意义及权限对文件目录的意义
转自:http://www.jb51.net/article/77458.htm linux中目录与文件权限的意义 一.文件权限的意义 r:可以读这个文件的具体内容: w:可以编辑这个文件的内容,包括 ...
- 限制SSH用户访问Linux中指定的目录
限制SSH用户访问Linux中指定的目录 http://os.51cto.com/art/201703/534895.htm#topx http://www.cnblogs.com/lykyl/arc ...
- linux中的重要目录
1./boot 引导程序,内核的存放的目录. 此目录,包含了在引导过程中所必须的文件,引导程序的相关文件(如:grub,lilo以及相应的配置文件及linux操作系统内核相关文件). 2./sbin/ ...
- 【转】完美解读Linux中文件系统的目录结构
一.前 言 接触Linux也有一段时间了,不过这几天在编译开源程序时,才发现自己对linux文件系统的目录结构了解的不够透彻,很多重要目录都说不清楚是用来干嘛的,于是在网上百度了一下这方面的介绍,根据 ...
- linux中VI编写C程序。。。
在linux中编写C程序时不像编写shell那样开头要#!/bin/bash,但是在C程序中要指定头文件(头文件是指输入输出,宏等,而且要首先声明,也是必须要开始就声明的) 写好C代码后要给C文件赋予 ...
- linux中rc.d目录下的文件
参考 http://blog.sina.com.cn/s/blog_414d78870102vqj5.html http://www.360doc.com/content/12/0820/17/933 ...
- Linux中Too many open files 问题分析和解决
今天某个服务的日志中出现了大量的异常: [WARN ] 2018-06-15 16:55:20,831 --New I/O server boss #1 ([id: 0x55007b59, /0.0. ...
- Windows转到linux中,文件乱码,文件编码转换 & 解决sqlplus连接oracle乱码
转载:http://www.cnblogs.com/wanyao/p/3399269.html 最近,学习又重新开始Linux学习,所以一直在Centos中,昨天一朋友把他在Windows下写的C程序 ...
- Linux中syntax error near unexpected token 错误提示解决方法
Linux中syntax error near unexpected token ... 错误提示有一般有两种原因: 1)window和Linux下换行符不一致导致 window下的换行和Linux下 ...
随机推荐
- 基于Hexo搭建静态博客
关于静态博客 通常来讲,建立个人博客有2种方式: 第一,直接在第三方博客平台注册博客空间,如:博客园,简书,CSDN等,这种方式建立的博客,所有数据都存放在博客平台. 第二,自建博客系统,这种方式就是 ...
- [OpenCV实战]33 使用OpenCV进行Hough变换
目录 1 什么是霍夫变换 1.1 应用霍夫变换以检测图像中的线条 1.2 累加器 1.3 线条检测 1.4 圆环的检测 2 代码 3 参考 1 什么是霍夫变换 霍夫变换是用于检测图像中的简单形状(诸如 ...
- MySQL 日期函数、时间函数在实际场景中的应用
整理日常业务中用到日期函数的一些场景,并对日期函数按照使用类型做了分类,实例也尽可能符合日常需求.为了方便查阅,可以先看目录,再根据需要看具体方法和实例. 首先明确日期和时间类型有哪些,也就是日期函数 ...
- 从0开始学习VUE3--01-Vue2与Vue3的不同点
升级带来的性能提升总结 1.模板编译优化:节点达到一定个数,会自动优化 每次重新渲染,会调用createVnode创建虚拟节点,VUE3会做静态提升,静态节点进行提取,进行优化 2.事件 缓存事件,防 ...
- 使用ng-zorro图标库出现the icon redo-o does not exist or is not registered.
出现这种情况一般是因为没导入你要的图标 可以在项目目录找到这个文件 src\style-icons-auto.ts 然后打开,导入导出里加上你要导入的图标.... 就可以了 如果你不知道要怎么加 ...
- 如何在阿里云服务器搭建flask
下载flask不用我多说了,pip3 install flask 今天在阿里云的服务器上测试一个Flask程序,命名指定了 ip:0.0.0.0,port:5000,但是外网IP确怎么也访问不了网页 ...
- Java CompletableFuture 异步超时实现探索
作者:京东科技 张天赐 前言 JDK 8 是一次重大的版本升级,新增了非常多的特性,其中之一便是 CompletableFuture.自此从 JDK 层面真正意义上的支持了基于事件的异步编程范式,弥补 ...
- FAQ selenium无法click的一个案例分享(1)
案例描述 http://sahitest.com/demo/php/fileUpload.htm 来自助教咨询 点击网页的第一个选择文件,如图 示例代码 from selenium import w ...
- springcloud04 Ribbbon
Ribbbon虽然现在已经进入维护模式了,但是使用的还是很多的. 1.官网 https://github.com/Netflix/ribbon/wiki/Getting-Started 2.Ribbo ...
- CNCF社区首个!KubeEdge达到软件供应链SLSA L3等级
摘要:在v1.13.0版本中,KubeEdge项目已达到 SLSAL3等级(包括二进制和容器镜像构件),成为CNCF社区首个达到SLSA L3等级的项目. 本文分享自华为云社区<CNCF社区首个 ...