简体   繁体   中英

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).

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. 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.

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 :

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:

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).

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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