C中的递归和链表

我正在创建一个函数,它接受一个路径并读取其中的所有文件并创建一个链接列表。 读取目录效果很好,但是我很难在链表中创建和存储相关信息以供日后使用。

这是我目前正在使用的结构:

typedef struct searchPool searchPool; struct searchPool{ char * path; char * fileName; char *pathFile; searchPool * next; }; 

创建“SearchPool”类型的新元素的函数定义如下:

 searchPool * mallocStructPool (char * path, char * fileName, char * filePath ) { searchPool * element = (searchPool*)malloc(sizeof(searchPool)); element->path = malloc(sizeof(char * )); element->fileName = malloc(sizeof(char * )); element->pathFile = malloc(sizeof(char * )); element->path = path; element->fileName = fileName; element->pathFile = filePath; element->next = NULL; return element; } 

最后,列出头部的递归函数就是这样编写的(如果向右滚动则代码注释):

 void listDir(char * path, searchPool * head){ DIR * d = opendir(path); // open the path searchPool * element; // create new Element of type SearchPool struct dirent * dir; // for the directory entries while ((dir = readdir(d)) != NULL) { // if we were able to read somehting from the directory if(dir-> d_type != DT_DIR) { // if the type is not directory just print it with blue char * s = malloc(sizeof(char*)+1); // variable to concatenate s = concat(path, dir->d_name); // concatenate path and filename together //printf("%s\n",s); element = mallocStructPool(dir->d_name, path, s); // malloc new element and set variables head->next = element; element->next = NULL; free(s); } else if(dir -> d_type == DT_DIR && strcmp(dir->d_name,".")!=0 && strcmp(dir->d_name,"..")!=0 ) {// if it is a directory char d_path[255]; // here I am using sprintf which is safer than strcat sprintf(d_path, "%s/%s", path, dir->d_name); listDir(d_path, element); // recall with the new path } } closedir(d); // finally close the directory } 

问题是当调用函数listDir()时,它最终只会打印我在其参数中给出的第一个路径,其余部分将被忽略。 每次运行后我是否必须在listDir()中返回新元素? 我不知道我哪里出错了。

任何帮助表示赞赏。 谢谢你的时间。

你的代码没有意义。 您不需要分配结构及其成员。 另外不要施放malloc的返回 。 你不检查malloc()的返回。 而且你不复制字符串。

在第二个函数中,您应该返回链表并检查opendir()返回函数。

这是一个例子:

 #include  #include  #include  #include  typedef struct searchPool searchPool; struct searchPool { char *path; char *fileName; char *pathFile; searchPool *next; }; static searchPool *mallocStructPool(char *path, char *fileName) { searchPool *element = malloc(sizeof *element); if (element == NULL) { goto error; } size_t path_size = strlen(path); element->path = malloc(path_size + 1); if (element->path == NULL) { goto free_element; } size_t fileName_size = strlen(fileName); element->fileName = malloc(fileName_size + 1); if (element->fileName == NULL) { goto free_path; } element->pathFile = malloc(path_size + 1 + fileName_size + 1); if (element->pathFile == NULL) { goto free_fileName; } memcpy(element->path, path, path_size); element->path[path_size] = '\0'; memcpy(element->fileName, fileName, fileName_size); element->fileName[fileName_size] = '\0'; memcpy(element->pathFile, path, path_size); element->pathFile[path_size] = '/'; memcpy(element->pathFile + path_size + 1, fileName, fileName_size); element->pathFile[path_size + 1 + fileName_size] = '\0'; return element; free_fileName: free(element->fileName); free_path: free(element->path); free_element: free(element); error: return NULL; } searchPool *listDir(char *path); static searchPool *listDir_aux(char *path, struct dirent *dirent) { if (dirent->d_type == DT_DIR && dirent->d_type != DT_LNK && strcmp(dirent->d_name, ".") != 0 && strcmp(dirent->d_name, "..") != 0) { size_t path_size = strlen(path); size_t name_size = strlen(dirent->d_name); char *d_path = malloc(path_size + 1 + name_size + 1); if (d_path == NULL) { return NULL; } memcpy(d_path, path, path_size); d_path[path_size] = '/'; memcpy(d_path + path_size + 1, dirent->d_name, name_size); d_path[path_size + 1 + name_size] = '\0'; searchPool *ret = listDir(d_path); free(d_path); return ret; } return mallocStructPool(path, dirent->d_name); } searchPool *listDir(char *path) { printf("%s\n", path); DIR *dir = opendir(path); if (dir == NULL) { perror("dir()"); return NULL; } searchPool *head = NULL; struct dirent *dirent; while ((dirent = readdir(dir)) != NULL) { searchPool *elem = listDir_aux(path, dirent); if (elem != NULL) { elem->next = head; head = elem; } } closedir(dir); return head; } int main(void) { searchPool *head = listDir("/tmp"); searchPool *tmp; for (searchPool *elem = head; elem != NULL; elem = tmp) { printf("%s, %s, %s\n", elem->path, elem->fileName, elem->pathFile); free(elem->path); free(elem->fileName); free(elem->pathFile); tmp = elem->next; free(elem); } } 

向尾部添加元素

  searchPool *ptr; searchPool *prev = 0; searchPool *head = something; for(ptr = head; ptr != NULL; ptr = ptr->next) prev = ptr; element->next = 0; prev->next = element; 

添加到头部(更快)

  element->next = head; head = element; 

注意头现在不稳定。

在头后添加一个

 element->next = head->next; head->next = element 

注意,head现在可能是一个虚拟节点,其中没有任何数据,为了拥有一个稳定且常量的“head”指向链表而存在;