实现ls 命令(-l -a -R)

-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’是不会自动刷新输出流,直至缓存被填满。

  1. 字符串替换’\0’
    终端显示结果

    执行代码
        test[strlen(test)] = '/';
        test[strlen(test) + 1] = '\0';
        printf( "test = %s\n",test);

看起来好像没什么问题但是终端的运行结果却和想象 的不一样

终端结果
在这里插入图片描述
虽然只增加了一个 ‘/’, 但是 当 ‘/’ 将test 的 ‘\0’ 替换掉,test 的长度 就有可能发生改变, 所以此时不能再用 第而行代码,而应该在改之前将 test 的长度备份, 替换 strlen 即可.

  1. 注意路径的拼接
  2. 颜色输出
\e[1; --开启颜色输出  + 颜色号码 + 字符串 + \e[0m 关闭颜色输出
  1. 对于链接文件,怎样找到它的源文件信息
    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 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值