Mac平台C语言目录遍历工具输入无效目录时卡顿无响应问题排查
目录遍历工具问题修复方案
问题根源
输入不存在的目录时程序卡顿,核心原因是主函数中错误的do-while循环逻辑:每次chdir(input)失败后就执行chdir(".."),只要当前目录不是根目录,chdir("..")就会返回0,导致无限循环,永远无法进入后续的错误处理流程。
同时代码还存在其他冗余与错误:
recursive_list中重复调用opendir,导致目录指针泄漏- 错误提示信息不清晰(如
perror("-1")) - 违反需求使用了
fgets读取输入
修复后的代码
#include <unistd.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <dirent.h> #include <errno.h> #include <sys/stat.h> // 使用系统定义的PATH_MAX,避免自定义值与系统实际限制冲突 #ifndef PATH_MAX #define PATH_MAX 256 #endif void recursive_list(const char *directory) { DIR *dir = opendir(directory); if (dir == NULL) { perror("Failed to open directory"); return; } struct dirent *ent; while ((ent = readdir(dir)) != NULL) { printf("%s\n", ent->d_name); } closedir(dir); } void myls(const char *directory) { if (!directory) { fprintf(stderr, "Error: Null directory pointer\n"); exit(EXIT_FAILURE); } struct stat st; // 直接验证路径是否存在且为目录 if (stat(directory, &st) == -1 || !S_ISDIR(st.st_mode)) { perror("Invalid directory"); return; } printf("%s\n", directory); recursive_list(directory); } int main() { char cwd[PATH_MAX]; char input[PATH_MAX]; ssize_t read_len; if (!getcwd(cwd, sizeof(cwd))) { perror("getcwd() failed"); return EXIT_FAILURE; } printf("Directory: "); // 使用read读取输入,满足"不使用fgets等函数"的需求 read_len = read(STDIN_FILENO, input, sizeof(input) - 1); if (read_len == -1) { perror("Failed to read input"); return EXIT_FAILURE; } // 处理输入:截断换行符,处理空输入 input[read_len] = '\0'; size_t input_len = strlen(input); if (input_len > 0 && input[input_len - 1] == '\n') { input[input_len - 1] = '\0'; input_len--; } if (input_len == 0) { // 无输入时使用当前目录 myls(cwd); } else { // 直接验证输入目录有效性,无需错误的chdir循环 myls(input); } return EXIT_SUCCESS; }
关键修改点
- 移除错误的
do-while循环:改用stat函数直接验证输入路径是否为有效目录,逻辑简洁且避免无限循环 - 修复资源泄漏:
recursive_list中只调用一次opendir,确保目录指针被正确关闭 - 替换输入读取方式:用
read替代fgets,满足需求限制 - 优化错误提示:使用清晰的错误信息,便于定位问题
- 对齐系统定义:使用系统原生的
PATH_MAX,避免自定义值引发的兼容性问题
验证逻辑说明
- 读取输入后自动处理换行符,判断是否为空输入,为空则使用当前目录
- 非空输入时,通过
stat函数做两层校验:- 校验路径是否存在、是否有权限访问
- 校验路径对应的文件类型是否为目录
- 有效目录则调用遍历函数输出条目,无效则直接打印错误信息
内容的提问来源于stack exchange,提问作者Raúl Armas
相关产品推荐
相关产品推荐

