递归列出文件的例程的奇怪错误
Posted
技术标签:
【中文标题】递归列出文件的例程的奇怪错误【英文标题】:Weird bug with routine to list files recursively 【发布时间】:2013-06-05 14:32:10 【问题描述】:任何人都可以发现我在这里缺少什么吗?该代码块应该递归访问目录并存储目录路径和其中文件的路径。如果文件是目录,它将 fprintf() 为 true,如果文件不是目录,则为 false。奇怪的是,fileName 的 printf 例程工作正常,但是当将 fprintf fileName 打印到文件时,它只是在应该打印 fileName 的地方打印一个换行符。
/* List the files in "dir_name". */
static void listDir(const char *dirName)
DIR *dir;
/*
* Open the directory specified by "dirName".
*/
dir = opendir(dirName);
/*
* Check it was opened.
*/
if (!dir)
fprintf(stderr, "Cannot open directory '%s': %s\n",
dirName, strerror(errno));
exit(EXIT_FAILURE);
while (1)
struct dirent *entry;
const char *dir_name;
/*
* "Readdir" gets subsequent entries from "d".
*/
entry = readdir(dir);
if (!entry)
/*
* There are no more entries in this directory, so break out of the while loop.
*/
break;
dir_name = entry->d_name;
char fileName[PATH_MAX];
// Assign fileName to path if the file is not a directory
if (entry->d_type != DT_DIR)
if (strcmp(dirName, "/") != 0)
snprintf(fileName, PATH_MAX,
"%s/%s", dirName, dir_name);
else
snprintf(fileName, PATH_MAX,
"%s%s", dirName, dir_name);
/* Access directory and leave out /. and /.. in the process
*/
if (entry->d_type == DT_DIR)
/*
* Check that the directory is not "d" or d's parent.
*/
if (strcmp(dir_name, "..") != 0 && strcmp(dir_name, ".") != 0)
int path_length;
char path[PATH_MAX], indexPath[PATH_MAX];
if (strcmp(dirName, "/") != 0)
path_length = snprintf(path, PATH_MAX,
"%s/%s", dirName, dir_name);
else
path_length = snprintf(path, PATH_MAX,
"%s%s", dirName, dir_name);
strcpy(indexPath, path);
strcat(indexPath, "/masterIndex.db");
FILE *fp;
if ((fp = fopen(indexPath, "a")) == NULL)
printf("Cannot open file\n");
return;
printf("File: %s\n (TRUE)\n", path);
printf("File: %s\n (FALSE)\n", fileName); // This routine prints fileName correctly
fprintf(fp, "%s\n", path);
fprintf(fp, "%s\n", "true");
fprintf(fp, "%s\n", fileName); // This routine prints a newline where fileName is supposed to be
fprintf(fp, "%s\n", "false");
fclose(fp);
// Activate this for screw ups
/*
char command[PATH_MAX];
strcpy(command, "cd ");
strcat(command, path);
strcat(command, " && rm abc *.finderDB .DS_Store");
printf("%s\n", command);
system(command);*/
if (path_length >= PATH_MAX)
fprintf(stderr, "Path length has gotten too long.\n");
exit(EXIT_FAILURE);
/*
* Recursively call "list_dir" with the new path.
*/
listDir(path);
/*
* After going through all the entries, close the directory.
*/
if (closedir(dir))
fprintf(stderr, "Could not close '%s': %s\n",
dirName, strerror(errno));
exit(EXIT_FAILURE);
【问题讨论】:
这个函数应该是listDir();
?顺便说一句:我没有看到任何对 opendir() 或 closedir() 的调用。请发布真实代码。
刚刚编辑了发布的代码。整个功能块现在就在那里。
***.com/questions/15068475/…。一个可以帮助您找到 findfirstfile 的示例。
【参考方案1】:
system("cd any_path")
不会对调用过程产生任何影响;改用chdir()
..
【讨论】:
系统(“cd path”)在代码中工作正常。如果函数向南并在我的主目录中乱扔索引文件,我只会取消注释该块。感谢 chdir() 的建议。将在以后的代码中使用它。 :) @NaveenMathewsystem("cd path")
“工作正常”,这是真的,但它并没有像你想象的那样做。它启动一个子进程,该进程执行您的 shell 程序,然后解释“cd path”字符串,更改目录,然后退出。它对程序的执行环境没有任何影响(除了浪费一点时间......)。
这个答案在回答 OP 的问题方面没有任何作用,是吗?【参考方案2】:
您在此处缺少初始化fileName
:
char fileName[PATH_MAX];
像这样修改这条线:
char fileName[PATH_MAX] = "";
不这样做可能会导致访问未初始化的变量,即未定义的行为,并可能导致任何或多或少的理性或非理性。
【讨论】:
仍然不工作......它仍然只是打印一个换行符,其中 fileName 应该是...... 我想我成功了。仍然不知道错误是什么,但我只是以另一种方式解决了这个问题。一旦我确定会发布我的代码...【参考方案3】:这是我设法修复的工作代码。仍然不知道错误是什么,但这应该适用于 POSIX 系统。不确定Windows。感谢 alk 的初始化建议,chidir() 的 xtof(我还没有实现)和 twalberg 解释 chdir() 的作用。
/* List the files in "dir_name". */
static void listDir(const char *dirName)
DIR *dir;
/*
* Open the directory specified by "dirName".
*/
dir = opendir(dirName);
/*
* Check it was opened.
*/
if (!dir)
fprintf(stderr, "Cannot open directory '%s': %s\n",
dirName, strerror(errno));
exit(EXIT_FAILURE);
while (1)
struct dirent *entry;
const char *dir_name;
/*
* "Readdir" gets subsequent entries from "d".
*/
entry = readdir(dir);
if (!entry)
/*
* There are no more entries in this directory, so break out of the while loop.
*/
break;
dir_name = entry->d_name;
if (entry->d_type != DT_DIR)
char fileName[PATH_MAX] = "", indexPath[PATH_MAX] = "";
if (strcmp(dirName, "/") != 0)
sprintf(fileName, "%s/%s", dirName, dir_name);
else
sprintf(fileName, "%s%s", dirName, dir_name);
strcpy(indexPath, dirName);
strcat(indexPath, "/masterIndex.db");
// We don't want to include masterIndex.db in the index list right?
if (strcmp(indexPath, fileName) != 0)
FILE *fp;
fp = fopen(indexPath, "a");
if (fp == NULL)
printf("Cannot open file\n");
printf("File: %s\n (FALSE)\n", fileName);
fprintf(fp, "%s\n", fileName);
fprintf(fp, "%s\n", "false");
fclose(fp);
/*
* See if "entry" is a subdirectory of "dir".
*/
if (entry->d_type == DT_DIR)
/*
* Check that the directory is not "d" or d's parent.
*/
if (strcmp(dir_name, "..") != 0 && strcmp(dir_name, ".") != 0
&& strcmp(dir_name, "tmp") != 0
&& strcmp(dir_name, "Jarvis") != 0)
int path_length;
char path[PATH_MAX] = "", indexPath[PATH_MAX] = "";
if (strcmp(dirName, "/") != 0)
path_length = sprintf(path,
"%s/%s", dirName, dir_name);
else
path_length = sprintf(path, "%s%s", dirName, dir_name);
strcpy(indexPath, path);
strcat(indexPath, "/masterIndex.db");
FILE *fp;
fp = fopen(indexPath, "a");
if (fp == NULL)
printf("Cannot open file\n");
printf("File: %s\n (TRUE)\n", path);
fprintf(fp, "%s\n", path);
fprintf(fp, "%s\n", "true");
fclose(fp);
// Activate this for screw ups
/*
char command[PATH_MAX];
strcpy(command, "cd ");
strcat(command, path);
strcat(command, " && rm abc *.finderDB .DS_Store");
printf("%s\n", command);
system(command); */
if (path_length >= PATH_MAX)
fprintf(stderr, "Path length has gotten too long.\n");
exit(EXIT_FAILURE);
/*
* Recursively call "list_dir" with the new path.
*/
listDir(path);
/*
* After going through all the entries, close the directory.
*/
if (closedir(dir))
fprintf(stderr, "Could not close '%s': %s\n",
dirName, strerror(errno));
exit(EXIT_FAILURE);
【讨论】:
以上是关于递归列出文件的例程的奇怪错误的主要内容,如果未能解决你的问题,请参考以下文章
我创建几个c文件,然后直接复制的例程C文件,编译错误Build target 'Target 1' compiling main.c... main
CreateProcess 和奇怪的 nslookup 错误