用"树"存储目录结构输出时出现了乱码
问题1: 存储某个文件目录结构时应用什么数据结构更为恰当?
问题2: 我的想法是用一般"树"结构来存储,但是有很多问题:
1.某个目录下的文件数可能不一样,这样每个树结点(只有目录才有子结点,叶结点为文件(或空 目录))的子结点数就不是确定的,这样可以在每个树结点中添加一个关键字
nchild
来表明其有
nchild
个子结点(即有
n
个指向子结点的指针
*child
,下面的程序采用
**child
来存储这 些指针).
2.这样一来就要动态地为
**child
的指向分配空间,可是这样一做后面就太不好释放(下面的程序压根就没有释放)? 这怎么办?
3.还有就是运行下面的程序有时会输出乱码的文件路径名,这是怎么回事?调试的时候发现是
ent=readdir(pDir)
读出了一个乱码的
ent->d_name
.但是单独写一个程序读同一个目录又没这种问题.我觉得可能递归调用出现了问题,但还是找不出问题的原因?希望大家花点时间帮忙看看,在这里谢过了.
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.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;
}
Oo凡星oO
11 years ago