此程序的目标是获取目录的命令行参数,并打印该目录下的前10个最大文件(包括子目录)。到目前为止,我只是试图让它以递归方式打印文件及其大小。我使用一个结构来包含文件名及其大小,并将这些结构存储在一个数组中。但由于某种原因,程序似乎没有将子目录文件的信息添加到数组中。排序似乎也是关闭的,但我认为这是同一问题的一部分,因为它为num_entries返回错误的值,因为它没有正确地记录所有文件。我确定这是递归逻辑中的某种缺陷,但我似乎无法找到它。如果有人可以向我提供正确方向的任何指示(ha),我将不胜感激。谢谢!
(这也是我在这里发表的第一篇文章,所以如果还有其他任何我做错了,格式化我的帖子也让我知道。)
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#define K 1024
#define CHUNK 16
typedef struct mls {
char *ml_name;
long ml_size;
} ML_ENTRY;
ML_ENTRY **getentries (int *num_entries, const char *name, int level);
void swap(ML_ENTRY *list[], int pos1, int pos2);
void quicksort(ML_ENTRY *list[], int n);
ML_ENTRY **getentries (int *num_entries, const char *name, int level)
{
DIR *dir;
struct dirent *entry;
struct stat st;
int rv;
int n;
int size;
char path[K];
ML_ENTRY **li;
if (!(dir = opendir (name)))
return;
if (!(entry = readdir (dir)))
return;
size = CHUNK;
n = 0;
li = malloc(size * sizeof(ML_ENTRY *));
while (entry = readdir (dir)){
if(n >= size){
size <<= 1;
li = realloc(li, size*sizeof(ML_ENTRY));
}
int len =
snprintf (path, sizeof (path) - 1, "%s/%s", name, entry->d_name);
rv = lstat(path, &st);
if (entry->d_type == DT_DIR){
path[len] = 0;
if (strcmp (entry->d_name, ".") == 0
|| strcmp (entry->d_name, "..") == 0)
continue;
getentries(num_entries, path, level + 1);
}
if (rv < 0)
continue;
li[n] = malloc(sizeof(ML_ENTRY));
li[n]->ml_name = strdup(entry->d_name);
li[n++]->ml_size = st.st_size;
}
closedir (dir);
*num_entries = n;
return li;
}
int main (int argc, char *argv[])
{
int nentries;
ML_ENTRY **list;
char dir[K];
int i;
if (argc > 1)
strcpy(dir, argv[1]);
else
strcpy(dir, ".");
list = malloc(sizeof(ML_ENTRY*));
list = getentries(&nentries, dir, 0);
quicksort(list, nentries);
for(i = 0; i < nentries; i++)
printf("%5d %s\n", list[i]->ml_size, list[i]->ml_name);
return 0;
}
void swap(ML_ENTRY *list[], int pos1, int pos2)
{
ML_ENTRY *tmp;
tmp = list[pos1];
list[pos1] = list[pos2];
list[pos2] = tmp;
}
void quicksort(ML_ENTRY *list[], int n)
{
int last;
int i;
if(n < 2)
return;
last = 0;
for(i=1;i<n;i++)
if(list[i]->ml_size > list[0]->ml_size)
swap(list, ++last, i);
swap(list, 0, last);
quicksort(list, last - 1);
quicksort(list + last + 1, n - last - 1);
}
void swap(ML_ENTRY *list[], int pos1, int pos2)
{
ML_ENTRY *tmp;
tmp = list[pos1];
list[pos1] = list[pos2];
list[pos2] = tmp;
}
void quicksort(ML_ENTRY *list[], int n)
{
int last;
int i;
if(n < 2)
return;
last = 0;
for(i=1;i<n;i++)
if(list[i]->ml_size > list[0]->ml_size)
swap(list, ++last, i);
swap(list, 0, last);
quicksort(list, last - 1);
quicksort(list + last + 1, n - last - 1);
}
答案 0 :(得分:1)
你说,
出于某种原因,程序似乎没有将子目录文件的信息添加到数组中。
在函数getentries
中,您有一个递归调用来处理子目录:
getentries(num_entries, path, level + 1);
正在忽略来自该递归调用的返回值。这就是为什么你没有看到输出中与子目录相对应的任何条目。
<强>更新强>
这是更新的函数,用于处理子目录的条目。
ML_ENTRY **getentries (int *num_entries, const char *name, int level)
{
DIR *dir;
struct dirent *entry;
struct stat st;
int rv;
int n;
int size;
char path[K];
ML_ENTRY **li;
// Add variables to deal with the entries from sub-directories.
ML_ENTRY **subDirectoryLi;
int subDirctoryNumEntries;
int i;
if (!(dir = opendir (name)))
return;
size = CHUNK;
n = 0;
li = malloc(size * sizeof(ML_ENTRY *));
while (entry = readdir (dir)){
if(n >= size){
size <<= 1;
li = realloc(li, size*sizeof(ML_ENTRY*));
}
int len =
snprintf (path, sizeof (path) - 1, "%s/%s", name, entry->d_name);
rv = lstat(path, &st);
if (entry->d_type == DT_DIR){
path[len] = 0;
if (strcmp (entry->d_name, ".") == 0
|| strcmp (entry->d_name, "..") == 0)
continue;
// Process the entries from the sub-directory.
subDirectoryLi = getentries(&subDirctoryNumEntries, path, level + 1);
for ( i = 0; i < subDirctoryNumEntries; ++i, ++n )
{
if(n >= size){
size <<= 1;
li = realloc(li, size*sizeof(ML_ENTRY*));
}
li[n] = subDirectoryLi[i];
}
}
if (rv < 0)
continue;
li[n] = malloc(sizeof(ML_ENTRY));
li[n]->ml_name = strdup(entry->d_name);
li[n++]->ml_size = st.st_size;
}
closedir (dir);
*num_entries = n;
return li;
}