使用 c 打印目录的程序不起作用,递归调用问题
Program to print directories using c not working, issues with recursive call
我需要创建一个基本上与 Linux 上的列表实用程序类似的程序。我一直在努力让它发挥作用,我已经很接近了,但现在我被卡住了。本质上,它将打印目录中包含的任何文件和子目录(即,如果 i 运行 ./project3,它会列出该目录中的任何内容)。但是,一旦我尝试使递归调用正常工作,它就会吐出如下内容:
sh: 1: /home/RageKage/Documents/Project3/dir1: Permission denied
这就是我卡住的地方,我不确定从这里开始做什么。我正在获取目录的路径以使用 realpath 进行探索并且工作正常,但是递归调用不起作用并且我不确定我做错了什么。任何帮助将不胜感激,因为我对此比较陌生。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <limits.h>
int main (int argc, char *argv[])
{
DIR *dir;
struct dirent *sd;
const char *direct;
char buf[PATH_MAX + 1];
if (argc < 2)
{
direct = ".";
}else{
direct = argv[1];
//printf("Hey this is argv[1]: %s\n", argv[1]);
}
dir = opendir(direct);
if (dir == NULL)
{
printf("ERROR! NO DIRECTORY TO OPEN!\n");
exit(1);
}
while( (sd=readdir(dir)) != NULL )
{
if (!strcmp(sd->d_name, ".") || !strcmp(sd->d_name, ".."))
{
}else{
printf("\n>> %s\n", sd->d_name);
}
if (!strcmp(sd->d_name, "..") || !strcmp(sd->d_name, "."))
{
}else if (sd->d_type == 4){
printf("Attempting to Run!\n");
realpath(sd->d_name, buf);
printf("[%s]\n", buf);
system(("./project3 %s", buf));
printf("\n");
}
}
closedir(dir);
return 0;
}
system(("./project3 %s", buf));
您是否再次递归调用程序本身?这听起来有点低效,而且很难做到,因为您需要知道可执行文件的位置。一般来说,它几乎可以在任何地方(从 /bin
、/usr/bin
等开始),而你在 argv[0]
中可能得到的只是文件名部分,而不是整个路径。
此外,如评论中所述,func((this, that))
与 func(that)
相同,而不是 func(this, that)
,因为括号使逗号充当逗号运算符,而不是参数分隔符。而且 system()
只接受一个参数,因此您需要使用 sprintf()
来构建命令行。 (或者也许使用 exec()
函数实际给出单独的参数而不调用 shell,但是你也需要执行 fork()
。)
我建议放弃这个想法,将目录树放入它自己的函数中,并递归调用它:
void walkpath(void)
{
DIR *dir = opendir(".");
struct dirent *sd;
while((sd = readdir(dir)) != NULL) {
/* ... */
if (sd->d_type == DT_DIR) {
chdir(sd->d_name);
walkpath();
chdir("..");
}
}
}
int main(...)
{
/* ... */
chdir(directory);
walkpath();
}
我在这里使用 chdir
来更改进程的工作目录以及遍历。如果您需要跟踪完整的目录名称,则需要添加它。
此外,现在您对 .
和 ..
进行了两次测试。使用 continue
结束循环的迭代,这样您就不需要再次测试相同的东西。
if (strcmp(sd->d_name, ".") == 0 || strcmp(sd->d_name, "..") == 0) {
continue;
}
我需要创建一个基本上与 Linux 上的列表实用程序类似的程序。我一直在努力让它发挥作用,我已经很接近了,但现在我被卡住了。本质上,它将打印目录中包含的任何文件和子目录(即,如果 i 运行 ./project3,它会列出该目录中的任何内容)。但是,一旦我尝试使递归调用正常工作,它就会吐出如下内容:
sh: 1: /home/RageKage/Documents/Project3/dir1: Permission denied
这就是我卡住的地方,我不确定从这里开始做什么。我正在获取目录的路径以使用 realpath 进行探索并且工作正常,但是递归调用不起作用并且我不确定我做错了什么。任何帮助将不胜感激,因为我对此比较陌生。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <limits.h>
int main (int argc, char *argv[])
{
DIR *dir;
struct dirent *sd;
const char *direct;
char buf[PATH_MAX + 1];
if (argc < 2)
{
direct = ".";
}else{
direct = argv[1];
//printf("Hey this is argv[1]: %s\n", argv[1]);
}
dir = opendir(direct);
if (dir == NULL)
{
printf("ERROR! NO DIRECTORY TO OPEN!\n");
exit(1);
}
while( (sd=readdir(dir)) != NULL )
{
if (!strcmp(sd->d_name, ".") || !strcmp(sd->d_name, ".."))
{
}else{
printf("\n>> %s\n", sd->d_name);
}
if (!strcmp(sd->d_name, "..") || !strcmp(sd->d_name, "."))
{
}else if (sd->d_type == 4){
printf("Attempting to Run!\n");
realpath(sd->d_name, buf);
printf("[%s]\n", buf);
system(("./project3 %s", buf));
printf("\n");
}
}
closedir(dir);
return 0;
}
system(("./project3 %s", buf));
您是否再次递归调用程序本身?这听起来有点低效,而且很难做到,因为您需要知道可执行文件的位置。一般来说,它几乎可以在任何地方(从 /bin
、/usr/bin
等开始),而你在 argv[0]
中可能得到的只是文件名部分,而不是整个路径。
此外,如评论中所述,func((this, that))
与 func(that)
相同,而不是 func(this, that)
,因为括号使逗号充当逗号运算符,而不是参数分隔符。而且 system()
只接受一个参数,因此您需要使用 sprintf()
来构建命令行。 (或者也许使用 exec()
函数实际给出单独的参数而不调用 shell,但是你也需要执行 fork()
。)
我建议放弃这个想法,将目录树放入它自己的函数中,并递归调用它:
void walkpath(void)
{
DIR *dir = opendir(".");
struct dirent *sd;
while((sd = readdir(dir)) != NULL) {
/* ... */
if (sd->d_type == DT_DIR) {
chdir(sd->d_name);
walkpath();
chdir("..");
}
}
}
int main(...)
{
/* ... */
chdir(directory);
walkpath();
}
我在这里使用 chdir
来更改进程的工作目录以及遍历。如果您需要跟踪完整的目录名称,则需要添加它。
此外,现在您对 .
和 ..
进行了两次测试。使用 continue
结束循环的迭代,这样您就不需要再次测试相同的东西。
if (strcmp(sd->d_name, ".") == 0 || strcmp(sd->d_name, "..") == 0) {
continue;
}