C语言模拟ls命令实现文件名按字母序排序编译报错如何解决
错误分析
编译警告的核心原因是strcpy入参类型不匹配:strcpy要求两个参数都是char*类型的字符串地址,但你传入的words2是char**二级指针,类型完全不兼容,所以触发了类型错误警告。除了这个编译问题外,你的代码还存在多个逻辑错误:
- 字符串交换逻辑错误:
words数组存储的是字符串指针,不需要拷贝字符串内容,直接交换指针地址即可完成元素交换 - 排序边界硬编码为10,只会处理前10个文件名,文件数超过10会漏排,少于10会访问空指针触发崩溃
- 使用
strcmp排序是区分大小写的,不符合你要求的不区分大小写排序需求 - 你存入
words数组的dir->d_name指向readdir的内部静态缓冲区,不需要手动释放,后续循环free(words[a])会触发野指针释放崩溃 - 不需要额外申请
words2二级数组当临时交换空间,只需要一个char*临时变量即可 - 排序后倒序输出,得到的是降序结果,不符合ls默认升序输出的逻辑
修复步骤
- 删掉没用的
words2数组申请,交换时只用一个char*临时变量 - 把排序边界改成实际读取到的文件数
count - 替换
strcmp为strcasecmp实现不区分大小写的比较(需要引入<strings.h>头文件) - 交换逻辑改成直接交换指针地址
- 删掉错误的
words[a]、words2[a]释放逻辑 - 调整输出逻辑为正序输出
修正后完整代码
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <ctype.h> #include <dirent.h> // 该程序用于模拟ls命令,实现扫描运行目录下所有文件并按序输出文件名的功能 int main(int argc, char* argv[]) { char **words = calloc(1000, sizeof(*words)); DIR *d; struct dirent *dir; // 目录条目指针 d = opendir("."); char* a = "."; char* b = ".."; char* c = "ls"; int ret1, ret2, ret3, count = 0; if (d) // 打开目录失败时opendir返回NULL { while ((dir = readdir(d)) != NULL) { ret1 = strcmp(dir->d_name, a); // 和当前目录比较 ret2 = strcmp(dir->d_name, b); // 和父目录比较 ret3 = strcmp(dir->d_name, c); // 和ls自身比较 if (ret1 == 0 || ret2 == 0 || ret3 == 0) { // 跳过.、..和ls程序自身 } else { words[count] = dir->d_name; // 将文件名存入数组 count++; } } // 冒泡排序,按不区分大小写的升序排列 for (int i = 0; i < count - 1; i++) { for (int j = 0; j < count - 1 - i; j++) { if (strcasecmp(words[j], words[j + 1]) > 0) { // 直接交换指针即可,不需要拷贝内容 char *temp = words[j]; words[j] = words[j + 1]; words[j + 1] = temp; } } } // 正序输出所有文件名 for (int i = 0; i < count; i++) { printf("%s\n", words[i]); } } // 关闭目录释放资源 closedir(d); free(words); return 0; }
内容的提问来源于stack exchange,提问作者Vearaa
相关产品推荐
相关产品推荐

