无法递归访问子文件夹
Not able to visit subfolders recursively
我正在尝试构建一个程序,递归地列出目录中的所有文件夹和文件,以及它们的文件大小。我仍在处理第一部分,因为该程序似乎只深入了一个子文件夹级别。
有人能发现这里的问题吗?我卡住了。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <strings.h>
#include <dirent.h>
#include <unistd.h>
void listdir(const char *name) {
DIR *dir;
struct dirent *entry;
int file_size;
if (!(dir = opendir(name)))
return;
if (!(entry = readdir(dir)))
return;
do {
if (entry->d_type == DT_DIR) {
char path[1024];
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
printf("./%s\n", entry->d_name);
listdir(entry->d_name);
}
else
printf("./%s\n", entry->d_name);
} while (readdir(dir) != NULL);
closedir(dir);
}
int main(void)
{
listdir(".");
return 0;
}
第一个问题是在while条件下,你放弃了readdir
的return值,应该赋值给entry。
此外,当递归调用 listdir
时,您应该在路径前加上父名称,否则它将始终从当前工作目录搜索。
试试这个版本:
void listdir(const char *name) {
DIR *dir;
struct dirent *entry;
int file_size;
if (!(dir = opendir(name)))
return;
while ((entry = readdir(dir)) != NULL) { // <--- setting entry
printf("%s/%s\n", name, entry->d_name);
if (entry->d_type == DT_DIR) {
char path[1024];
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
sprintf(path, "%s/%s", name, entry->d_name); // <--- update dir name properly by prepend the parent folder.
listdir(path);
}
}
closedir(dir);
}
int main(void)
{
listdir(".");
return 0;
}
以下是对您的代码的最小修正。我在这里冒昧地使用了非标准的 asprintf
;如果你不使用 glibc,你应该使用 snprintf
或类似的东西。
最值得注意的是,给listdir
的路径必须是当前工作目录的完整相对路径;或绝对路径。然而 entry->d_name
中的那个只是文件的基本名称。因此它必须与传递给 listdir
的路径连接起来。我还将不合适的 do
...while
更改为 while
循环。
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <strings.h>
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void listdir(const char *path) {
DIR *dir;
struct dirent *entry;
if (!(dir = opendir(path)))
return;
while ((entry = readdir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
char *current;
if (asprintf(¤t, "%s/%s", path, entry->d_name) < 0) {
// asprintf failed
fprintf(stderr, "asprintf failed, exiting");
goto exit;
}
puts(current);
if (entry->d_type == DT_DIR) {
listdir(current);
}
free(current);
}
exit:
closedir(dir);
}
int main(void)
{
listdir(".");
}
我正在尝试构建一个程序,递归地列出目录中的所有文件夹和文件,以及它们的文件大小。我仍在处理第一部分,因为该程序似乎只深入了一个子文件夹级别。
有人能发现这里的问题吗?我卡住了。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <strings.h>
#include <dirent.h>
#include <unistd.h>
void listdir(const char *name) {
DIR *dir;
struct dirent *entry;
int file_size;
if (!(dir = opendir(name)))
return;
if (!(entry = readdir(dir)))
return;
do {
if (entry->d_type == DT_DIR) {
char path[1024];
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
printf("./%s\n", entry->d_name);
listdir(entry->d_name);
}
else
printf("./%s\n", entry->d_name);
} while (readdir(dir) != NULL);
closedir(dir);
}
int main(void)
{
listdir(".");
return 0;
}
第一个问题是在while条件下,你放弃了readdir
的return值,应该赋值给entry。
此外,当递归调用 listdir
时,您应该在路径前加上父名称,否则它将始终从当前工作目录搜索。
试试这个版本:
void listdir(const char *name) {
DIR *dir;
struct dirent *entry;
int file_size;
if (!(dir = opendir(name)))
return;
while ((entry = readdir(dir)) != NULL) { // <--- setting entry
printf("%s/%s\n", name, entry->d_name);
if (entry->d_type == DT_DIR) {
char path[1024];
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
sprintf(path, "%s/%s", name, entry->d_name); // <--- update dir name properly by prepend the parent folder.
listdir(path);
}
}
closedir(dir);
}
int main(void)
{
listdir(".");
return 0;
}
以下是对您的代码的最小修正。我在这里冒昧地使用了非标准的 asprintf
;如果你不使用 glibc,你应该使用 snprintf
或类似的东西。
最值得注意的是,给listdir
的路径必须是当前工作目录的完整相对路径;或绝对路径。然而 entry->d_name
中的那个只是文件的基本名称。因此它必须与传递给 listdir
的路径连接起来。我还将不合适的 do
...while
更改为 while
循环。
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <strings.h>
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void listdir(const char *path) {
DIR *dir;
struct dirent *entry;
if (!(dir = opendir(path)))
return;
while ((entry = readdir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
char *current;
if (asprintf(¤t, "%s/%s", path, entry->d_name) < 0) {
// asprintf failed
fprintf(stderr, "asprintf failed, exiting");
goto exit;
}
puts(current);
if (entry->d_type == DT_DIR) {
listdir(current);
}
free(current);
}
exit:
closedir(dir);
}
int main(void)
{
listdir(".");
}