简体   繁体   中英

Using an array of filenames stored as strings

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?

When you pass an array to a function, it decays to a pointer, so when you do eg &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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM