1

我正在尝试将文件名存储在数组中。该数组在一个结构中,我想存储在数组中的目录中找到的文件的名称。但是,我用来存储名称的过程似乎在此过程中损坏了 2 或 3 个名称。我认为问题出在strdup关键字上。每当我运行我的程序时,它要么读取程序可执行文件(位于我从中读取文件的目录上方的目录中),要么读取存储在前几个数组位置的奇怪符号。以下是我尝试捕获和存储文件名的程序的一部分,以及输出结果的图片:

typedef struct{
  char *filename;
}filename;

typedef struct Configs{
  char file_data_path[50];
  char event_log_path[50];
  filename *fn_data;
}Configs;

typedef struct TestConfigs{
  bool done;
  int selection;
  int attempts_counter;
  Configs tConfig;
}TestConfigs;

void read_files(struct TestConfigs *setup);

int main(void) {
  printf("Hello Test\n");
  TestConfigs setup;
  read_files(&setup);
  system("pause");
  return EXIT_SUCCESS;
}

void read_files(struct TestConfigs *setup)
{
  setup->done = false;
  setup->attempts_counter = 3;

  char cwd[1024];
  DIR *dir = NULL;
  struct dirent *pent = NULL;
  struct stat info;
  int total_num_of_files = 0;

  strcpy(setup->tConfig.file_data_path, "data/");

  chdir(setup->tConfig.frame_data_path);
  if((getcwd(cwd, sizeof(cwd))) != NULL)
  {
      printf("Current Directory: %s\n", cwd);
  }

  dir = opendir(cwd);

  if(dir != NULL)
  {
     while((pent = readdir(dir)) != NULL)
     {
         if(stat(pent->d_name, &info))
         {
             printf("ERROR: stat%s: %s\n", pent->d_name, strerror(errno));
         }
         else
         {
             if(S_ISREG(info.st_mode))
             {
                 if((strcmp(pent->d_name, ".cproject") == 0) || (strcmp(pent->d_name, ".project") == 0))
                 {
                     continue;
                 }
                 else
                 {
                     total_num_of_files++;
                 }
             }
         }
     }
     printf("# of files found: %d\n", total_num_of_files);
     rewinddir(dir);

     // SETUP ARRAY HERE!
     setup->tConfig.fn_data = malloc(total_num_of_files);
     total_num_of_files= 0;

     printf("During Storage Process:\n");
     while((pent = readdir(dir)) != NULL)
     {
         if(stat(pent->d_name, &info))
         {
             printf("ERROR: stat%s: %s\n", pent->d_name, strerror(errno));
         }
         else
         {
             if(S_ISREG(info.st_mode))
             {
                 if((strcmp(pent->d_name, ".cproject") == 0) || (strcmp(pent->d_name, ".project") == 0))
                 {
                     continue;
                 }
                 else
                 {
                     setup->tConfig.fn_data[total_num_of_files].filename = (char*)malloc(sizeof(pent->d_name));
                     setup->tConfig.fn_data[total_num_of_files].filename = strdup(pent->d_name);  // <- Possible source of the storage problem
                     printf("Filename stored in fn_data[%d] = %s\n", total_num_of_files, setup->Config.fn_data[total_num_of_files].filename);
                     total_num_of_files++;
                 }
             }
         }
     }

     printf("\n");
     printf("After Storage Process:\n");
     for(int i = 0; i < total_num_of_files; i++)
     {
         printf("Filename stored in fn_data[%d] = %s\n", i, setup->tConfig.fn_data[i].filename);
     }
  }
  closedir(dir);
}

在这里输出结果

我可以做些什么来解决前几个数组位置中文件名的损坏存储?为什么只有前几个位置没有正确存储文件名,但其他位置都可以?是否存在问题strdup,如果是,那么在数组中捕获和存储文件名的好方法是什么?提前致谢!

4

2 回答 2

2

setup->tConfig.fn_data = malloc(total_num_of_files);

每个文件一个字节?

需要,例如,setup->tConfig.fn_data = malloc(total_num_of_files * sizeof(filename));

于 2018-03-01T15:58:30.517 回答
2

这个:

setup->tConfig.fn_data[total_num_of_files].filename = (char*)malloc(sizeof(pent->d_name));
setup->tConfig.fn_data[total_num_of_files].filename = strdup(pent->d_name);  // <- Possible source of the storage problem

没有意义; 将strdup()覆盖返回的指针,malloc()并且该内存将永远丢失(“泄漏”),这是不好的。

您不必为 分配内存strdup(),它会为您执行此操作。基本上是:

char * strdup(const char *s)
{
  const size_t sz = strlen(s) + 1;
  char * const p = malloc(sz);
  if (p != NULL)
    memcpy(p, s, sz);
  return p;
}
于 2018-03-01T15:48:49.800 回答