尝试在 C 中创建代码,打印从传递的根目录开始的所有目录
Trying to create code in C that print all directories starting from a root directory passed
示例
假设我有一个名为 Alpha 的目录,我想将其作为根目录。
- Alpha 包含:一些文件和其他两个目录 Beta 和 Gamma,
- Beta 包含:一些文件和另一个名为 Theta 的目录,
- Gamma 包含:一些文件,
- Theta 包含:一些文件。
INPUT/OUTPUT
使用输入为:./myfind Alpha
我想要输出:
Alpha
Beta
Gamma
Theta
(我不关心顺序)。
我的代码
我尝试使用此代码,但它不起作用。我想做一个递归函数来做它,我不能使用 POSIX.
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#if !defined(NAME_MAX)
#define NAME_MAX 256
#endif
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "ERROR: Run as ./myfind directory\n");
exit(EXIT_FAILURE);
}
const char *dir = argv[1];
struct stat statbuf;
stat(dir, &statbuf);
if (!S_ISDIR(statbuf.st_mode)) {
fprintf(stderr, "FATAL ERROR: %s IS NOT A DIRECTORY\n", dir);
exit(EXIT_FAILURE);
}
find(dir);
exit(EXIT_SUCCESS);
}
问题是递归到子目录时更改了当前目录,但从递归函数返回时没有更改回父目录。
您可以在 find
函数的末尾添加一个 chdir("..");
,但它可能不适用于所有情况:
- 如果一个目录有超过 2 个硬链接
- 如果你遍历符号链接
最好通过连接 passed_dir_name
、/
和 dir->d_name
来计算对 find()
的递归调用的目标目录路径,并避免更改当前目录。
这里是 find()
的修改版本,用于简化方法:
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
chdir("..");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
chdir("..");
}
示例
假设我有一个名为 Alpha 的目录,我想将其作为根目录。
- Alpha 包含:一些文件和其他两个目录 Beta 和 Gamma,
- Beta 包含:一些文件和另一个名为 Theta 的目录,
- Gamma 包含:一些文件,
- Theta 包含:一些文件。
INPUT/OUTPUT
使用输入为:./myfind Alpha
我想要输出:
Alpha
Beta
Gamma
Theta
(我不关心顺序)。
我的代码 我尝试使用此代码,但它不起作用。我想做一个递归函数来做它,我不能使用 POSIX.
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#if !defined(NAME_MAX)
#define NAME_MAX 256
#endif
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "ERROR: Run as ./myfind directory\n");
exit(EXIT_FAILURE);
}
const char *dir = argv[1];
struct stat statbuf;
stat(dir, &statbuf);
if (!S_ISDIR(statbuf.st_mode)) {
fprintf(stderr, "FATAL ERROR: %s IS NOT A DIRECTORY\n", dir);
exit(EXIT_FAILURE);
}
find(dir);
exit(EXIT_SUCCESS);
}
问题是递归到子目录时更改了当前目录,但从递归函数返回时没有更改回父目录。
您可以在 find
函数的末尾添加一个 chdir("..");
,但它可能不适用于所有情况:
- 如果一个目录有超过 2 个硬链接
- 如果你遍历符号链接
最好通过连接 passed_dir_name
、/
和 dir->d_name
来计算对 find()
的递归调用的目标目录路径,并避免更改当前目录。
这里是 find()
的修改版本,用于简化方法:
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
chdir("..");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
chdir("..");
}