-R 是 三个中最难实现的 ,就分享一下 遇到的问题.
第一次
刚开始 实现 -R 的时候只能在查看比较小的目录,如果 测试 根目录,几秒就会炸掉. 而且 这次 递归是 如果遇到一个目录,在将其展开,一直展开到最底层 return ,也就是 dfs . 而一般 的需求 是要求 一层 一层展开 (bfs).
第二次
采用 bfs 递归
存储 : 为了避免 栈溢出,这次用 molloc 申请空间,
char **filenames = (char **)malloc(sizeof(char *) * count);
for(int i = 0;i < count;i++) //count 为 文件的个数
{
filenames[i] = (char *)malloc(sizeof(char) * PATH_MAX + 1);
}
然后就 自己调用自己就ok
问题 :
1: 在 用 printf 调试的时候 发现不加 ‘\n’ 是不输出 的
因为 linux上标准输入输出都是带有缓存的,一般是行缓存。对于标准输出,需要输出的数据并不是直接输出到终端上,而是首先缓存到某个地方,当遇到行刷新标志或者该缓存已满的情况下,才会把缓存的数据显示到终端设备上。ANSI C中定义换行符’\n’可以认为是行刷新标志。所以,printf函数没有带’\n’是不会自动刷新输出流,直至缓存被填满。
- 字符串替换’\0’
终端显示结果
执行代码
test[strlen(test)] = '/';
test[strlen(test) + 1] = '\0';
printf( "test = %s\n",test);
看起来好像没什么问题但是终端的运行结果却和想象 的不一样
终端结果
虽然只增加了一个 ‘/’, 但是 当 ‘/’ 将test 的 ‘\0’ 替换掉,test 的长度 就有可能发生改变, 所以此时不能再用 第而行代码,而应该在改之前将 test 的长度备份, 替换 strlen 即可.
- 注意路径的拼接
- 颜色输出
\e[1; --开启颜色输出 + 颜色号码 + 字符串 + \e[0m 关闭颜色输出
- 对于链接文件,怎样找到它的源文件信息
readlink 函数
头文件: #include <unistd.h>
int readlink(const char *path, char *buf, size_t bufsiz);
path 路径名
buf 将找到的信息存放在buf中
bufsiz buf的长度,若超过了bufsiz 的长度,信息会丢失
实现代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<sys/stat.h>
#include<unistd.h>
#include<sys/types.h>
#include<linux/limits.h>
#include<dirent.h>
#include<grp.h>
#include<pwd.h>
#include<errno.h>
#define PARAM_NONE 0 //无参数
#define PARAM_A 1 //-a 显示所有文件
#define PARAM_L 2 // -l 一行只显示一个文件的详细信息
#define PARAM_R 4 //-R 递归显示目录
#define MAXROWLEN 80 //一行显示的最多字符数
#define BLUE "\e[0;34m"
#define L_BLUE "\e[1;34m"
void display_dir(int flag_param,char *path);
int g_leave_len = MAXROWLEN; //一行剩余长度,用于输出对齐
int g_maxlen; //存放某目录下最长文件名的长度
//错误处理函数 ,打印出错误所在行的行数和错误信息
int flag_param = PARAM_NONE;
void my_err(const char * err_string,int line)
{
fprintf(stderr,"line:%d ",line);
perror(err_string);
}
// 选项 l 获取文件属性并打印
void display_attribute(struct stat buf,char *name)
{
char buf_time[32];
struct passwd *psd; //从该结构体中获取文件所有者的用户名
struct group *grp; //从该结构体中获取文件所有者所属组的组名
int flag = 0; //用来 判断是否是 链接文件
//获取并打印文件类型
if(S_ISLNK(buf.st_mode))printf( "l"); //判断是否为链接文件
else if(S_ISREG(buf.st_mode)) printf( "-"); //判断是否为一般文件
else if(S_ISDIR(buf.st_mode)) printf("d"); //判断是否为目录文件
else if(S_ISCHR(buf.st_mode)) printf( "c"); //判断是否为字符设备文件
else if(S_ISBLK(buf.st_mode)) printf( "b"); //判断是否为快设备文件
else if(S_ISFIFO(buf.st_mode)) printf( "f"); //判断是否为先进先出 FIFO
else if(S_ISSOCK(buf.st_mode)) printf( "s"); //判断是否为socket
//获取并打印文件所有者的权限
if(buf.st_mode & S_IRUSR) printf( "r");
else printf( "-");
if(buf.st_mode & S_IWUSR) printf( "w");
else printf( "-");
if(buf.st_mode & S_IXUSR) printf( "x");
else printf( "-");
//获取并打印与文件所有者同组的用户对该文件的操作权限
if(buf.st_mode & S_IRGRP) printf( "r");
else printf( "-");
if(buf.st_mode & S_IWGRP) printf( "w");
else