首先是参数的解析,尽管此次仅要求完成ls三个功能选项,但是即便只有三个功能选项,加上n个文件路径的参数, 手动解析这样的参数还是动作有点多.
还好,Linux提供了一个专门用于解析命令的函数:
getopt()
示例如下:
#include<stdio.h>
#include<unistd.h>
int main(int argc , char ** argv){
int oc;
char ec;
while((oc = getopt(argc,argv,"laR")) != -1){
switch(oc){
case 'l':
printf("有l选项\n");
break;
case 'a' :
printf("有a选项\n");
break;
case 'R' :
printf("有R选项\n");
break;
case '?' :
printf("不支持的参数\n");
break;
}
}
}
getopt()函数每次执行从参数argv中解析出来一个第三个参数包含的选项,并返回,处理完成后 ,它会将原参数中的选项移动到所有参数的最前面.
例如:
执行: my_ls /home -a
int ch;
ch = getopt(argc,argv,"aRl");
完成后,ch的值为a
argv变为 {“my_ls\0”,”-a\0”,”/home\0”}
然后关于递归显示文件夹的过程中,需要保存各级文件夹的完整路径,如果按照固定大小的数组来保存的话,大概递归到第7层就会爆堆栈,因此在递归过程中,使用结合目录下文件/目录数目以及最长文件名来动态申请的二级数组,在当前函数完成后立即释放相关数据,即可做到完整递归 / 目录. 相关代码如下
申请过程:
DIR *dir;
struct dirent *ptr;
int count = 0;
int i = 0 ;
char **filename;
struct stat buf;
g_maxlen = 0;
//获取给定文件夹下的文件数目和最长文件名
dir = opendir(path);
if (dir == NULL) {
if(errno == 13){
printf("my_ls: 无法打开目录 '%s' :权限不够\n",path);
return;
}
}
while ((ptr = readdir(dir)) != NULL) {
if (g_maxlen < strlen(ptr->d_name)) {
g_maxlen = strlen(ptr->d_name);
}
count++;
}
closedir(dir);
filename = (char **) malloc(sizeof(void *) * count);
if(filename == NULL) my_err("内存申请失败",__LINE__);
for (i = 0; i < count; i++) {
filename[i] = (char *) malloc(strlen(path) + g_maxlen + 2);
if(filename[i] == NULL) my_err("内存申请失败",__LINE__);
}
释放过程
for(i = 0; i < count; i++){
free(filename[i]);
}
free(filename);