Функция qsort() в c используется для сравнения массива строк

Я пытаюсь воссоздать команду Linux ls в C. у меня есть работающая программа (просматривая список каталогов, переданных в качестве аргументов командной строки, и помещая все содержимое в массив строк).

Сейчас я пытаюсь реализовать флаг быстрой сортировки для команды (например, ls -s /dev), который должен распечатать все содержимое в лексикографическом порядке. Проблема в том, что qsort() метод в stdlib.h только "сортирует" один элемент (в основном меняет местами первый и последний элемент в массиве) для моей программы.

Я понятия не имею, что не так, так как все мои указатели также правильно установлены. Я добавляю соответствующие фрагменты кода ниже, пожалуйста, дайте мне знать, если что-то бросается в глаза, что ускользает от моего в течение двух дней.

Функция сравнения для 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);
}  

Обновление файла BufferCurrentPointer:

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 работает только один раз (технически даже не проходит через массив один раз, а не рекурсивно несколько раз для завершения алгоритма).

1 ответ

Решение

Вы сделали общую ошибку, полагая, что функция сравнения берет два элемента из вашего массива - она ​​фактически использует два указателя на элементы в вашем массиве, поэтому вы должны вызвать strcmp следующим образом

int normalCompare (const void *stringOne, const void *stringTwo) {
   return strcmp(*(const char **)stringOne, *(const char **)stringTwo);
}
Другие вопросы по тегам