简体   繁体   English

使用存储为字符串的文件名数组

[英]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]); 当我将filename设置为类似于"file.txt"的字符串时,它可以工作,所以当我执行printf("n %s\\n", filesArray[i]);时,这也不应该工作吗printf("n %s\\n", filesArray[i]); ? Is filesArray[i] in this line of code a string? 这行代码中的filesArray[i]是字符串吗?


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. 当您将数组传递给函数时,它会衰减为指针,因此当您执行&arr您实际上会获得指向该指针的指针,而指针的大小很可能不是原始数组的大小。 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). 如果(实际上是如果)数组实际上是一个字符串,则可以使用strlen来获取字符串的长度(不包括字符串终止符)。

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. 在您的情况下,实际上并不需要 getArraySize函数,因为您已经有一个计数器来告诉您filesArray数组中有多少个字符串: filesCtr变量。


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. 同样,当使用诸如readdir之类的函数时,返回条目的d_name字段实际上可能指向静态数组,因此您不能只复制指针,而必须复制完整的字符串。 This is done with the strdup function: 这是通过strdup函数完成的:

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

Remember that when done you have to free this string. 请记住,完成后必须free此字符串。


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 ). 哦,并且避免在代码中使用“幻数”,例如,在检查目录条目是否为子目录( ent->d_type == 4 )时。 Use the macros available to use ( end->d_type == DT_DIR ). 使用可用的宏( 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. 最后, readdir条目的d_name字段仅包含实际文件名,而不包含完整路径。 So if you want the full path you have to append the path and the filename. 因此,如果要使用完整路径,则必须附加路径和文件名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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