在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下 ...
随机推荐
- vue使用echarts引入离线地图(geo.json)并切换省市(以四川为例)
https://blog.csdn.net/weixin_43374193/article/details/95594419 https://blog.csdn.net/harrisonz8/arti ...
- 含辞未吐,声若幽兰,史上最强免费人工智能AI语音合成TTS服务微软Azure(Python3.10接入)
所谓文无第一,武无第二,云原生人工智能技术目前呈现三足鼎立的态势,微软,谷歌以及亚马逊三大巨头各擅胜场,不分伯仲,但目前微软Azure平台不仅仅只是一个PaaS平台,相比AWS,以及GAE,它应该是目 ...
- JavaWeb项目编译前后的目录结构
JavaWeb项目编译前后的目录结构 编译前 页面和视图都放在webapp目录下 编译后 webapps WEB-INF
- 软件安装——tortoiseGit安装和配置
Tortoisegit安装指南 TortoiseGit是一个开放的Git版本控制系统的源客户端,它是Git和Windows资源管理器的整合,提供了Git的图形化操作界面 一.软件安装 1.进入tort ...
- iOS14新特性
6月23日凌晨,苹果首次在线上举办全球开发者大会WWDC2020.在大会上,苹果对iOS.iPadOS.macOS.watchOS.tvOS进行更新,其中大家最关心的iOS14,主要更新了36个功能. ...
- LeetCode-343. 整数拆分 - 题解分析
题目来源 343. 整数拆分 题目详情 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化. 返回 你可以获得的最大乘积 . 示例 1: 输入: ...
- 三种循环的区别-break语句
三种循环的区别 循环语句的区别 for 和 while 的小区别: 控制条件语句所控制的那个变量,在for循环结束后,就不能再被访问到了,而while循环结束还可以继 续使用,如果你想继续使用,就用w ...
- 行为型模式 - 责任链模式Chain of Responsibility
我就想知道我又哪里有广告植入了,告诉我. 学习而来,代码是自己敲的.也有些自己的理解在里边,有问题希望大家指出. 模式的定义与特点 责任链(Chain of Responsibility)模式的定义: ...
- 一键部署nfs、rsync、sersync
一键部署nfs.rsync.sersync 项目代码: 链接:https://pan.baidu.com/s/13I0BBAYsdK-KmPekZ5VpdA 提取码:u2tw --来自百度网盘超级会员 ...
- SpringBoot 三大开发工具,你都用过么?
本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...