Unix/Linux实践编程——ls实现绝对路径

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

根据《Unix/Linux实践编程》第三章中的给出的 ls 代码,添加对于绝对路径的显示

提示:以下是本篇文章正文内容,下面案例可供参考

一、思路

其实这个给出的代码已经很全了,只是我们在输入类似 /tmp 参数时,perror总是会输出找不到这个目录或者文件,原因是 direntp->d_name 这个参数记录的是目录下面的第一个文件的name,而我们需要的是绝对路径的name也就是 /tmp/fistname
可以做一个测试,把tmp这个目录里面的文件全部搬到 ls.c 这个文件的目录下,再运行代码就清楚了。(参数给 /tmp 测试的时候)

二、使用步骤

1.引入库

代码如下(示例):

#include <time.h>
#include <stdio.h>
#include <grp.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>
void do_ls(char[]);
void dostat(char *);
void show_file_info(char *,struct stat *);
void mode_to_letters(int ,char[]);
char *uid_to_name(uid_t);
char *gid_to_name(gid_t);

int main (int ac,char *av[]){
	if (ac == 1){
		do_ls(".");
	}
	else{
		while (--ac){
			printf("%s\n",*++av);
			do_ls(*av);
		}
	}
	return 0;
}

void do_ls(char dirname[]){
	DIR *dir;
	int count=0;
	char buf[255]={'\0'};
	struct dirent *direntp;
	if ((dir=opendir(dirname)) == NULL){
		fprintf(stderr,"ls1,can't open %s\n",dirname);
		exit(1);
	}
	else {
	if (strchr(dirname,'/')){	//在dirname中查看是否存在 ‘/’ 这个字符,存在则返回当前字符的位置(可以用char *指针接受),不存在就返回0
		strcpy(buf,dirname);
		count=strlen(buf);
		buf[count]='/';  //给/tmp加上一个 / == /tmp/
		//方便后面加上filename
	}
		while ((direntp = readdir(dir))!=NULL){
			if (count){
			strcpy(dirname,buf);
			strcat(dirname,direntp->d_name);
			strcpy(direntp->d_name,dirname);
			dostat(direntp->d_name);		//这里丢掉了绝对路径,所以我们需要把绝对路径给它加上去
			}
			else
			dostat(direntp->d_name);		//
		}									//
			closedir(dir);
	}	
}

void dostat(char *filename){
	struct stat info;
	if ((stat(filename,&info)) == -1){
		perror(filename);
	}
	else{
		show_file_info(filename,&info);
	}
}

void show_file_info(char *filename,struct stat * info_p){
	char modestr[11];
	mode_to_letters(info_p->st_mode,modestr);
	printf("%s",modestr);
	printf("%4d ",(int)info_p->st_nlink);
	printf("%-8s ",uid_to_name(info_p->st_uid));
	printf("%-8s ",gid_to_name(info_p->st_gid));
	printf("%8ld ",(long)info_p->st_size);
	printf("%.12s ",4+ctime(&info_p->st_mtime));
	printf("%s\n",filename);
}

void mode_to_letters(int mode,char str[]){
	strcpy(str,"----------");

	if (S_ISDIR(mode) ) str[0]='d';
	if (S_ISCHR(mode) ) str[0]='c';
	if (S_ISBLK(mode) ) str[0]='b';

	if (mode & S_IRUSR) str[1]='r';
	if (mode & S_IWUSR) str[2]='w';
	if (mode & S_IXUSR) str[3]='x';

	if (mode & S_IRGRP) str[4]='r';
	if (mode & S_IWGRP) str[5]='w';
	if (mode & S_IXGRP) str[6]='x';

	if (mode & S_IROTH) str[7]='r';
	if (mode & S_IWOTH) str[8]='w';
	if (mode & S_IXOTH) str[9]='x';
}

char *uid_to_name(uid_t uid){
	struct passwd * pw_ptr;
	static char numstr[10];

	if ((pw_ptr = getpwuid(uid)) == NULL){
		sprintf(numstr,"%d",uid);
		return numstr;
	}
	else
		return pw_ptr->pw_name;
}

char *gid_to_name(gid_t gid){
	struct group  * grp_ptr;
	static char numstr[10];

	if ((grp_ptr = getgrgid(gid)) ==NULL){
		sprintf(numstr,"%d",gid);
		return numstr;
	}
	else 
		return grp_ptr->gr_name;
}

总结

写给自己:多敲、多看、多想、多动手

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

小白书舍

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值