【发布时间】:2015-02-04 04:45:15
【问题描述】:
该程序的目标是获取目录的命令行参数,并打印该目录下最大的 10 个文件(包括子目录)。到目前为止,我只是想让它递归地打印文件及其大小。我正在使用一个结构来包含文件名及其大小,并将这些结构存储在一个数组中。但由于某种原因,该程序似乎没有将子目录文件的信息添加到数组中。排序似乎也关闭了,但我认为这是与返回错误值 num_entries 相同的问题的一部分,因为它没有正确说明所有文件。我确信这是递归逻辑中的某种缺陷,但我似乎无法找到它。如果有人可以向我提供正确方向的任何指示(哈),我将不胜感激。谢谢!
(这也是我在这里的第一篇文章,所以如果我在格式化我的帖子方面做错了什么,也请告诉我。)
#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);
}
【问题讨论】:
-
需要考虑的一些限制。可能不适用于您的问题。每次递归将超过 1k 字节添加到堆栈 1) 堆栈是否足够大? 2) 1k 够长吗?
-
int len = snprintf (path, sizeof (path) - 1, ... path[len] = 0;是个问题,因为len可能大于sizeof (path)。
标签: c file recursion structure ls