C 从头开始递归地编写ls

C 从头开始递归地编写ls,c,linux,directory,C,Linux,Directory,我正在做一个简单的项目,从头开始实现“ls-R”。每当我运行我的程序时,我的程序总是一遍又一遍地搜索根目录。我做错了什么 void lsR(char dirName[]) { /* The recursive function call. */ DIR *dir; struct dirent *directory; struct stat fileStat; char type; char **nameList[MAX_RECURSIVE_FILES]; struct passwd *us

我正在做一个简单的项目,从头开始实现“ls-R”。每当我运行我的程序时,我的程序总是一遍又一遍地搜索根目录。我做错了什么

void lsR(char dirName[]) {
/*
The recursive function call.  
*/

DIR *dir;
struct dirent *directory;
struct stat fileStat;
char type;
char **nameList[MAX_RECURSIVE_FILES];
struct passwd *user;
int count = 0;
int i = 0;


printf("\n");
printf("./%s :\n", dirName);
printf("\n");


if ((dir = opendir(dirName)) == NULL) {
    perror("opendir error:");
    return;
}

while ((directory = readdir(dir)) != NULL) {


    if (stat(directory->d_name, &fileStat) < 0) {
        perror("fstat error:");
        return;
    }
    if (fileStat.st_uid == 1) {
        continue;
    }

    user = getpwuid(fileStat.st_uid);
    printf("%s ", directory->d_name);

    fileType(&fileStat, &type);
    if ((type == 'd') && (count < MAX_RECURSIVE_FILES)) {

        nameList[count] = malloc(sizeof(char)*MAX_STRING_LENGTH);
        strncpy(nameList[count++], directory->d_name, MAX_STRING_LENGTH);
    }

}
closedir(dir);
printf("\n");
for (i=0; i<count; i++) {
    printf("Calling lsR on: %s\n", nameList[i]);
    lsR(nameList[i]);
}
void lsR(char dirName[]{
/*
递归函数调用。
*/
DIR*DIR;
struct dirent*目录;
struct stat fileStat;
煤焦类型;
字符**名称列表[最大递归文件];
结构passwd*用户;
整数计数=0;
int i=0;
printf(“\n”);
printf(“./%s:\n”,dirName);
printf(“\n”);
if((dir=opendir(dirName))==NULL){
perror(“opendir错误:”);
返回;
}
而((directory=readdir(dir))!=NULL){
if(stat(directory->d_name,&fileStat)<0){
perror(“fstat错误:”);
返回;
}
如果(fileStat.st_uid==1){
继续;
}
user=getpwuid(fileStat.st_-uid);
printf(“%s”,目录->d_名称);
文件类型(&fileStat,&type);
if((type='d')&&(countd_名称,最大字符串长度);
}
}
closedir(dir);
printf(“\n”);

对于(i=0;i您需要包含相对于程序当前目录的路径。每个
nameList
元素都需要是
dirName
+
“/”
+
目录->d_名称


如果您开始在本地目录上调用
lsR
/foo
foo
下有名为
bar
的目录,那么要打开
bar
,您需要打开
/foo/bar
,因为您的程序是从curr文件列表中的
所代表的目录运行的您注意到的ent目录
第一个是指向当前目录的硬链接,第二个是指向父目录的硬链接。因此,当您通过dir项递归时,您希望跳过这两个目录。否则,您将递归到的第一个目录将是
,换句话说,就是您所访问的目录我刚过去

这是您的程序当前行为的原因,但一旦修复,您将遇到他在回答中提到的问题潜伏者

补充说明:

  • 您确定
    char**nameList[MAX\u RECURSIVE\u FILES];
    变量吗?在我看来,您想要的是
    char*
    数组,而不是
    char**
    数组
  • 您是否知道可以在
    stat
    结构的
    st\u mode
    字段上使用
    S\u ISDIR
    宏,以检查当前文件是否不是目录而不是自定义函数

dirName到底是什么?@newalchemy
dirName
是您传递给函数的内容。换句话说,您需要将整个相对路径与任何要打开的目录名一起携带。我实际上在自定义函数中使用了该宏-我只是编写了一个自定义函数,因为我想要一个返回字母的函数。我应该这样做不过也可以使用它。至于跳过.and..目录,我应该在I=2而不是I=0开始循环吗?@newalchemy,我从来没有见过一个目录没有
在第一个位置,但我找不到一个来源表明它是有保证的。所以跳过前两个条目肯定会在大多数情况下起作用时间(一直?),但如果您想确定,请将
目录->d_名称
进行比较。