1

So I'm struggling on a recursive function to enter a directory and it's subdirectories to save all the file names and a counter for the number of files. I don't know if this is the best way to save the file names, but I don't see any other way. I'm having problems passing the array of pointers and the file counter to the function.

Sorry for any absurd code.

Here's what I have:

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <dirent.h> int main(int argc, char *argv[]) { char * path = argv[1]; char ** tempFiles = NULL; int fileCounter = 0; findFilesRecursive(&fileCounter, &tempFiles, path); for (int i = 0; i < fileCounter; i++) printf("\n[%d]: %s", i, tempFiles[i]); } void findFilesRecursive(int * fileCounter, char ** tempFiles, char * path) { DIR * dirStream; struct dirent * entry; if(!(dirStream = opendir(path))) return; while ((entry = readdir(dirStream)) != NULL) { if (entry->d_type == DT_DIR) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; char fullPath[strlen(path) + strlen(entry->d_name) + 1]; sprintf(fullPath, "%s%s/", path, entry->d_name); findFilesRecursive(&(*fileCounter), &tempFiles, fullPath); } else if (entry->d_type == DT_REG) { char filePath[strlen(path) + strlen(entry->d_name)]; sprintf(filePath, "%s%s", path, entry->d_name); printf("FILE: %s\n", filePath); tempFiles = (char **) realloc(tempFiles, (*fileCounter + 1) * sizeof(char *)); tempFiles[*fileCounter] = (char *) MALLOC(strlen(filePath) * sizeof(char)); strcpy(tempFiles[*fileCounter], filePath); (*fileCounter)++; } } closedir(dirStream); } 
3
  • You may define a new counter variable in the if (entry->d_type == DT_DIR) { and pass a pointer to it, instead of a shared variable. That way you don't need to rely on it to be initialised properly. And to avoid too many reallocs you could have created a structure that holds a pointer to a pointer to a char and additional fields that could hold say current capacity and number of elements in a collection. Commented Oct 24, 2017 at 22:03
  • You never initialize tempFiles to any sane value. You pass its address to findFilesRecursive, and then pass that address to realloc. That doesn't make any sense -- you can only use realloc to either get a brand new block (in which case, you must pass it NULL) or to enlarge an existing block you got from malloc or realloc. Commented Oct 24, 2017 at 22:18
  • I'm sorry for the incomplete code, I changed it. Commented Oct 24, 2017 at 22:24

1 Answer 1

1

Your compiler should have warned you that &tempFiles, as in:

findFilesRecursive(&(*fileCounter), &tempFiles, fullPath);

is a char ***, yet you promised the compiler that tempFiles would be a char **. It is very tempting to be “&” happy in C, but really you should restrict it to an ‘as needed’ basis - it makes the code more understandable. The construct &(*fileCounter) had me scratching my head, after 30+ years of programming in C.

Sign up to request clarification or add additional context in comments.

2 Comments

I honestly was changing and trying different possibilities, because, as I stated, I'm not very experient in using char ** or char ***, I'm sorry for that. How would I correctly pass tempFiles to the function?
Just pass tempfiles as is. I think this should work: findFilesRecursive(fileCounter, tempFiles, fullPath). Think like this: my argument tempFiles is a char ** and now i want to give it to a function that expects a char **. But tempFiles is a char ** already so i have nothing to do. Same rationale goes for fileCounter.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.