0

My program iterates through a single directory (non-recursively) and stores the names of all the files in that directory inside an array. Then, it uses that array in the second part of my program and returns some information about each file. I can iterate through the directory, and I can process a single file, but I'm having trouble combining the two parts of the program. Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>

int getArraySize(char* arr[]);
int getArraySize(char* arr[]) {
  return sizeof(&arr);
}

char *filesArray[200];
int main (int argc, char* argv[])
{
  DIR *dir;
  struct dirent *ent;
  int filesCtr = 0;
  if ((dir = opendir ("/home/dshah/Documents/CECS 420/Project 3")) != NULL) {
    while ((ent = readdir (dir)) != NULL) {     /* print all the files and directories within directory */
      if (strcmp(ent->d_name, ".") == 0) {
        continue;
      } else if (strcmp(ent->d_name, "..") == 0) {
        continue;
      } else if (ent->d_type == 4) { // if a directory
        continue;
      } else {
        filesArray[filesCtr] = ent->d_name;
        printf("%s\n", filesArray[filesCtr]);
        filesCtr++;
      }
    }
    closedir (dir);
  } else {     /* could not open directory */
    perror ("Could not open directory");
  }

  int i;
  for (i = 0; i < getArraySize(filesArray); i++) {
    char* filename = filesArray[i];
    FILE *file = fopen (filename, "r");
    if (file != NULL) {
      char line [128]; /* or other suitable maximum line size */
      int ctr = 1;
      while (fgets(line, sizeof line, file) != NULL) { /* read a line */
        if (strstr(line, "is") != NULL) {
          printf("%s:%d:%s", filename, ctr, line);
        }
        ctr++;
      }
      fclose (file);
    } else {
      perror (filename); /* why didn't the file open? */
    }
  }
  return 0;
}

The line I am having trouble with is:

char* filename = filesArray[i];

Is this line of code correct? It works when I set filename to a string like "file.txt", so shouldn't this also work when I do printf("n %s\n", filesArray[i]);? Is filesArray[i] in this line of code a string?


EDIT:

Thanks, that fixed the problem. One more quick question: I'm trying to append the full path on

FILE *file = fopen (filename, "r");`

line by changing it to

FILE *file = fopen (strcat("/home/dshah/Documents/CECS 420/Project 3/", filename), "r"); 

but it gives me a segmentation fault. Shouldn't this work cause I'm just specifying the path?

1 Answer 1

1

When you pass an array to a function, it decays to a pointer, so when you do e.g. &arr you actually get a pointer to that pointer, and the size of a pointer is most likely not the size of the original array. If (and I mean really if) the array is actually a string, you can use strlen to get the length of the string (not including the string terminator character).

In your case, you don't actually need the getArraySize function, as you already have a counter telling you how many strings there is in the filesArray array: The filesCtr variable.


Also, when using a function such as readdir the d_name field of the returned entry may actually be pointing to a static array so you can't really just copy the pointer, you have to copy the complete string. This is done with the strdup function:

filesArray[filesCtr] = strdup(ent->d_name);

Remember that when done you have to free this string.


Oh, and avoid using "magic numbers" in your code, for example when checking if the directory entry is a sub-directory (ent->d_type == 4). Use the macros available to use (end->d_type == DT_DIR).


And a final thing, the d_name field of the readdir entry only contains the actual filename, not the full path. So if you want the full path you have to append the path and the filename.

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

1 Comment

Thank you very much...that really helped. It was the strdup() function that fixed the issue. Also a question regarding the free(filesArray), when do I need to use that cause im getting some errors if I free it? Also very last question, I'm trying to append the full path on "FILE *file = fopen (filename, "r");" line by changing it to "FILE *file = fopen (strcat("/home/dshah/Documents/CECS 420/Project 3/", filename), "r");" but it gives me a segmentation fault. Shouldn't this work cause i'm just specifying the path. Thanks I appreciate it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.