Using qsort for character array in C

后端 未结 3 900
我在风中等你
我在风中等你 2021-01-05 01:28

I\'m trying to use qsort to sort a character array. I can\'t see why this is not working. I have a pointer to the compare function as the man pag

3条回答
  •  青春惊慌失措
    2021-01-05 02:09

    The problem is with the type cast operator in the the compare function comfunc.

    int cmpfunc(const void *a, const void *b) {
      // error. casting to int * instead of char *
      return *(int*)a - *(int*)b; 
    }
    

    Casting the void pointer a to int * and then dereferencing it means it will read the sizeof(int) bytes from the start of the address contained in a. So the expression in the return statement is comparing the sizeof(int) number of bytes from the address in a with the sizeof(int) number of bytes from the address in b, instead of comparing the characters at the addresses contained in the pointers a and b. To illustrate this, I changed the compare function to

    int cmpfunc(const void *a, const void *b) {
      printf("comparing %c and %c\n", *((char *)a), *((char *)b));
      printf("compare as int %d - %d = %d\n", *(int *)a, *(int *)b, *(int *)a - *(int *)b);
      printf("compare as char %d - %d = %d\n", *(char *)a, *(char *)b, *(char *)a - *(char *)b);
      return *(char *)a - *(char *)b;
    }
    

    And this is the output I get

    comparing b and c
    compare as int 1634034530 - 1684104547 = -50070017
    compare as char 98 - 99 = -1
    comparing a and d
    compare as int 25697 - 100 = 25597
    compare as char 97 - 100 = -3
    comparing e and a
    compare as int 6578533 - 25697 = 6552836
    

    You can see the difference in the values read when comparison is done after typecasting to int *, and after typecasting to char *. The compare function should be changed to

    int cmpfunc(const void *a, const void *b) {
          // typecast the void pointers to correct type
          return *(char *)a - *(char *)b; 
    }
    

    Also, you don't need to cast the result of strlen function and sizeof operator as they already return values of type size_t. Also, it is more readable and maintainable to use sizeof on the array element. You should simply call qsort as

    qsort(str, strlen(str), sizeof str[0], cmpfunc);
    

提交回复
热议问题