问题1:保存目录结构的最佳数据结构是什么?
问题2:我试着用一个通用树来解决,但是有很多问题:
目录下的文件数不确定。因此树节点下的子节点数量也不确定。我尝试向每个节点添加一个关键字nchild,显示nchild子节点。因此有指向子节点的nchild指针(与**child一起保存)。一旦这样,**child*child就应该动态地分配空间,而不需要特定的子节点。所以你知道,要释放这些空间是非常困难的(下面的程序不叫free())。有没有更好的解决办法?
有时当我输出directory tree时,下面的程序会得到垃圾字符,这让我非常困惑。调试时发现,函数ent=readdir(pDir);已读取垃圾字符。但当我编写另一个简单的程序来读取同一个目录时,一切都很顺利。我认为问题出在递归函数上,但我不知道。如果有人能给我个主意,我将不胜感激。谢谢!
` `

#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>

typedef struct tree_file_s
{
  char path[512];
  time_t date;
  char type;
  long size;
  int nchild;

  struct tree_file_s **child;
} tree_file_t;

int dir_child_len(const char *dir)
{
  int nchild = 0;
  DIR *pDir;
  struct dirent *ent;

  pDir = opendir(dir);
  while((ent=readdir(pDir)) != NULL)
  {
    if (strcmp(ent->d_name, ".")==0 || strcmp(ent->d_name, "..")==0)
    {
      continue;
    }
    nchild++;
  }

  return nchild;
}

void tree_create(tree_file_t *tft, const char *dir)
{
  int nchild; // the tft has n child
  DIR *pDir;
  struct dirent *ent; // the directory dir dirent info
  struct stat file_stat; // the new file's stat info

  stat(dir, &file_stat);
  nchild = dir_child_len(dir);
  pDir = opendir(dir);

  // Initialize the parent
  //tft->path = calloc(1, strlen(dir)+1);
  strcpy(tft->path, dir);
  tft->date = file_stat.st_mtime;
  tft->type = 'D';
  tft->size = file_stat.st_size;
  tft->nchild = nchild;
  tft->child = calloc(1, nchild);

  nchild = 0;
   while ((ent=readdir(pDir)) != NULL)
   {
      if (ent->d_type & DT_DIR)
      {
         if (strcmp(ent->d_name, ".")==0 || strcmp(ent->d_name, "..")==0)
         {
           continue;
         }
         tree_file_t *new_dir = calloc(1, sizeof(tree_file_t));
         tft->child[nchild] = new_dir;

         char *new_path = calloc(1, strlen(dir)+strlen(ent->d_name)+1);
         sprintf(new_path, "%s/%s", dir, ent->d_name);
         tree_create(new_dir, new_path);
         free(new_path);
      } else {
        tree_file_t *new_file = calloc(1, sizeof(tree_file_t));
        char *new_path = calloc(1, strlen(dir)+strlen(ent->d_name)+1);
        // new_file->path = calloc(1, strlen(dir)+strlen(ent->d_name)+1);
        sprintf(new_path, "%s/%s", dir, ent->d_name);
        stat(new_path, &file_stat);
        strcpy(new_file->path, new_path);
        free(new_path);
        new_file->date = file_stat.st_mtime;
        new_file->type = 'F';
        new_file->size = file_stat.st_size;
        new_file->nchild = 0;
        new_file->child = 0;

        tft->child[nchild] = new_file;
      }
      //free(new_path);
      //new_path = 0;
      nchild++;
   }
}

void display_tree(tree_file_t *tft)
{
  int nchild, i;

  nchild = tft->nchild;

  printf("%c: %s\n", tft->type, tft->path);

  for(i = 0; i < nchild; i++)
  {
    if(tft->child[i]->type == 'F')
    {
      printf("%c: %s\n",  tft->child[i]->type, tft->child[i]->path);
    } else {
      display_tree(tft->child[i]);
    }
  }
}

int main(int argc, const char *argv[])
{
  if(argc != 2)
  {
    printf("Usage: a.out dir\n");
    exit(0);
  }

  char dir[512];
  strcpy(dir, argv[1]);
  tree_file_t *tft = calloc(1, sizeof(tree_file_t));
  tree_create(tft, dir);
  display_tree(tft);

  return 0;
}

` `

最佳答案

当为new_path分配空间时,需要添加2(一个用于斜线,一个用于空终止符)。并且永远不会关闭打开的目录(使用closeDir())。
更严重的错误是这一行:

tft->child = calloc(1, nchild);

它只分配nchild字节,不足以容纳nchild指针!尝试:
tft->child = calloc(nchild, sizeof(*tft->child));

10-07 14:36