Reputation: 73
the following code opens a path and recursively reads through the directories and prints the files within it. At the moment it just prints the path to the directory and then every file within it but I would like to implement a linked list that will contain 1 char* variable that contains the full path to every file visited.
Here's the code :
#include <dirent.h>
#include <stdio.h>
#include <string.h>
void show_dir_content(char * path)
{
DIR * d = opendir(path);
if(d==NULL) return;
struct dirent * dir;
while ((dir = readdir(d)) != NULL)
{
if(dir-> d_type != DT_DIR) // if the type is not directory just print it
printf("\t%s\n",dir->d_name);
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);
printf("%s\n",d_path);
show_dir_content(d_path);
}
}
closedir(d);
}
int main(int argc, char **argv)
{
show_dir_content(argv[1]);
return(0);
}
The struct used for the linked list can be quite simple such as :
typedef struct search search;
struct search {
char *path;
char *fileName;
char *fullPathToFile;
search *next;
};
I'm just having a difficult time using mallocs for the struct and creating the actual linked list within the recursive function. Any help is appreciated.
Upvotes: 0
Views: 110
Reputation: 13533
You need to create a new search
node every time you find a file. Fill in the new node, then add it to the end of the list.
const char *path_format = "%s/%s";
// Modified to take a node ptr. This should be the last node in the list
// Returns a node ptr. This is the new last node in the list
search * show_dir_content(char * path, search *node)
{
DIR * d = opendir(path);
if(d==NULL) return node;
struct dirent * dir;
while ((dir = readdir(d)) != NULL)
{
if(dir-> d_type != DT_DIR) {
// Found a file. Alloc a new search node and fill in
// (TODO: You should check the return from malloc for failure)
search *new_node = malloc(sizeof(search));
// TODO: copy all the names. Hint: strdup
new_node->next = NULL;
// Append to end of list
node->next = new_node;
// Update node pointer to now point to the new node
node = node->next;
}
else
if(dir -> d_type == DT_DIR && strcmp(dir->d_name,".")!=0 && strcmp(dir->d_name,"..")!=0 ) // if it is a directory
{
// Not sure 255 chars will be enough....
char d_path[255]; // here I am using sprintf which is safer than strcat
sprintf(d_path, path_format, path, dir->d_name);
printf("%s\n",d_path);
// Make sure you update the node pointer to reflect any
// changes made in the recursive call
node = show_dir_content(d_path, node);
}
}
closedir(d);
// Return the last node (this may be same as input parameter if no files found
return node;
}
Update main
to create a root node and pass that to the function
int main(int argc, char **argv)
{
search root = {0};
show_dir_content(argv[1], &root);
// Note that root is a dummy node.
// The list actually begins at root->next
// Also, before you exit, free all mem
search *node = root.next, *next;
while (NULL != node) {
free(node->path);
free(node->fileName);
free(node->fullPathToFile);
next = node->next;
free(node);
node = next;
}
return(0);
}
Upvotes: 1
Reputation: 43
I think you can modify your prototype to add a struct search *
param wich gonna be the head pointeur of your list.
And when u need to put an element in your list just add a node in queue (or in head if u want but u need a struct search **
instead of a simple pointer.
And then when u need to put an element just call the function which gonna create an element and place it where u want.
After that u will just give to every recursive call the head ptr
of your list
Upvotes: 0