c中的qsort()函数用于比较字符串数组
qsort() function in c used to compare an array of strings
我正在尝试在 C 中重新创建 Linux 命令 ls
。我的程序正在运行(通过作为命令行参数传递的目录列表,并将所有内容推送到字符串数组)。
现在我正在尝试为命令(例如 ls -s /dev
)实现快速排序标志,它应该按字典顺序打印出所有内容。问题是 stdlib.h
中的 qsort()
方法对于我的程序只有 "sorts" 一个元素(基本上交换数组中的第一个和最后一个元素)。
我不知道出了什么问题,因为我的所有指针也已正确设置。我在下面添加了相关的代码片段,如果有什么东西引起了您的注意并且已经逃脱了我的两天,请告诉我。
qsort
的比较函数:
int normalCompare (const void *stringOne, const void *stringTwo) {
return strcmp((const char *)stringOne, (const char *)stringTwo);
}
实际函数调用:
void execute_ls(char **directoryList, Flags flags) {
//Create a buffer for directories' file names
char **fileNamesList;
fileNamesList = malloc(MAX_FILES * sizeof (*fileNamesList));
int fileBufferCurrentPointer = 0;
//Fill the buffer out by calling execute_ls_one_dir on all the directories
int i = 0;
while(directoryList[i] != NULL) {
execute_ls_one_dir(directoryList[i], fileNamesList, &fileBufferCurrentPointer);
i++;
}
fileNamesList[fileBufferCurrentPointer] = NULL;
//Process the array
if(flags.s == 1) {
qsort(fileNamesList, fileBufferCurrentPointer, sizeof (char *), normalCompare);
}
else if(flags.r == 1) {
qsort(fileNamesList, fileBufferCurrentPointer, sizeof (char *), reverseCompare);
}
//Print to user
for(i = 0; i < fileBufferCurrentPointer; i++) {
if(((*fileNamesList[i] == '.') && (flags.a == 1)) || (*fileNamesList[i] != '.')) {
printf("%s\n", fileNamesList[i]);
}
}
//Deallocate fileNamesList
for(i = 0; i < MAX_FILES; i++) {
free(fileNamesList[i]);
}
free(fileNamesList);
}
正在更新文件缓冲区当前指针:
while((oneDirEntryPtr = readdir(currentDirPtr)) != NULL) {
// Push the file name onto the fileNamesList array
fileNamesList[*fileBufferCurrentPointer] = malloc(MAX_LEN_NAME * sizeof (char));
strcpy(fileNamesList[*fileBufferCurrentPointer], oneDirEntryPtr->d_name);
*fileBufferCurrentPointer += 1;
}
我很困惑为什么 qsort
只工作一次(技术上什至不是一次通过数组而不是递归多次来完成算法)。
您犯了一个常见的错误,认为比较函数是从您的数组中获取两个元素 - 它实际上是获取两个指向您数组中元素的指针,因此您应该像这样调用 strcmp
int normalCompare (const void *stringOne, const void *stringTwo) {
return strcmp(*(const char **)stringOne, *(const char **)stringTwo);
}
我正在尝试在 C 中重新创建 Linux 命令 ls
。我的程序正在运行(通过作为命令行参数传递的目录列表,并将所有内容推送到字符串数组)。
现在我正在尝试为命令(例如 ls -s /dev
)实现快速排序标志,它应该按字典顺序打印出所有内容。问题是 stdlib.h
中的 qsort()
方法对于我的程序只有 "sorts" 一个元素(基本上交换数组中的第一个和最后一个元素)。
我不知道出了什么问题,因为我的所有指针也已正确设置。我在下面添加了相关的代码片段,如果有什么东西引起了您的注意并且已经逃脱了我的两天,请告诉我。
qsort
的比较函数:
int normalCompare (const void *stringOne, const void *stringTwo) {
return strcmp((const char *)stringOne, (const char *)stringTwo);
}
实际函数调用:
void execute_ls(char **directoryList, Flags flags) {
//Create a buffer for directories' file names
char **fileNamesList;
fileNamesList = malloc(MAX_FILES * sizeof (*fileNamesList));
int fileBufferCurrentPointer = 0;
//Fill the buffer out by calling execute_ls_one_dir on all the directories
int i = 0;
while(directoryList[i] != NULL) {
execute_ls_one_dir(directoryList[i], fileNamesList, &fileBufferCurrentPointer);
i++;
}
fileNamesList[fileBufferCurrentPointer] = NULL;
//Process the array
if(flags.s == 1) {
qsort(fileNamesList, fileBufferCurrentPointer, sizeof (char *), normalCompare);
}
else if(flags.r == 1) {
qsort(fileNamesList, fileBufferCurrentPointer, sizeof (char *), reverseCompare);
}
//Print to user
for(i = 0; i < fileBufferCurrentPointer; i++) {
if(((*fileNamesList[i] == '.') && (flags.a == 1)) || (*fileNamesList[i] != '.')) {
printf("%s\n", fileNamesList[i]);
}
}
//Deallocate fileNamesList
for(i = 0; i < MAX_FILES; i++) {
free(fileNamesList[i]);
}
free(fileNamesList);
}
正在更新文件缓冲区当前指针:
while((oneDirEntryPtr = readdir(currentDirPtr)) != NULL) {
// Push the file name onto the fileNamesList array
fileNamesList[*fileBufferCurrentPointer] = malloc(MAX_LEN_NAME * sizeof (char));
strcpy(fileNamesList[*fileBufferCurrentPointer], oneDirEntryPtr->d_name);
*fileBufferCurrentPointer += 1;
}
我很困惑为什么 qsort
只工作一次(技术上什至不是一次通过数组而不是递归多次来完成算法)。
您犯了一个常见的错误,认为比较函数是从您的数组中获取两个元素 - 它实际上是获取两个指向您数组中元素的指针,因此您应该像这样调用 strcmp
int normalCompare (const void *stringOne, const void *stringTwo) {
return strcmp(*(const char **)stringOne, *(const char **)stringTwo);
}