简体   繁体   English

c中的qsort()函数用于比较字符串数组

[英]qsort() function in c used to compare an array of strings

I am trying to recreate the Linux command ls in C. I have the program working (going through a list of directories passed in as command line arguments, and pushing all the contents to an array of strings). 我试图在C中重新创建Linux命令ls 。我正在运行该程序(浏览作为命令行参数传入的目录列表,并将所有内容推入字符串数组)。

Now I'm trying to implement the quicksort flag for the command (eg ls -s /dev ), which should print out all the contents in a lexicographical order. 现在,我正在尝试为命令(例如ls -s /dev )实现quicksort标志,该标志应按字典顺序打印所有内容。 The problem is that the qsort() method in stdlib.h only "sorts" one element (basically swaps the first and the last element in the array) for my program. 问题是stdlib.h中的qsort()方法仅对我的程序“排序”一个元素(基本上交换数组中的第一个和最后一个元素)。

I have no idea what's wrong, as all my pointers are properly set up as well. 我不知道出了什么问题,因为我的所有指针也都正确设置了。 I'm adding the relevant snippet codes below, please let me know if something catches your eye that has been escaping mine for two days. 我要在下面添加相关的代码段代码,请让我知道是否有什么东西让您的视线已经逃避了我两天。

Compare function for qsort : 比较qsort函数:

int normalCompare (const void *stringOne, const void *stringTwo) {
   return strcmp((const char *)stringOne, (const char *)stringTwo);
}  

Actual function call: 实际函数调用:

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);
}  

Updating the fileBufferCurrentPointer: 更新fileBufferCurrentPointer:

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;
}  

I'm confused as to why qsort is only working once (technically isn't even passing through the array once instead of recursively multiple times to complete the algorithm). 我对为什么qsort只工作一次感到困惑(从技术上讲,它甚至没有一次通过数组,而是多次递归地完成算法)。

you've made a common mistake in thinking the comparison function is taking two elements from your array - it's actually taking two pointers to elements in your array so you should call strcmp like this 您在认为比较函数从数组中获取两个元素时犯了一个常见错误-实际上是通过两个指向数组中元素的指针,因此应像这样调用strcmp

int normalCompare (const void *stringOne, const void *stringTwo) {
   return strcmp(*(const char **)stringOne, *(const char **)stringTwo);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM