I am trying to write a program that compares strings by their length and sorts them with qsort. I have been able to make them sort alphabetically, now I'm trying to sort them by length. What am I doing wrong with my comparison method? I'm unsure about pointers and feel that issue lies there. Thanks
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int stringCmp(const void *str1, const void *str2); //Function prototype.
int main (int argc, char *argv[])
{
int i;
char **arr = malloc(argc * sizeof(char *));
printf("Original Args:\n");
for (i = 0; i < argc-1; i ){
arr[i] = argv[i 1];
printf("%s\n",arr[i]);
}
qsort(arr, argc-1, sizeof *arr, stringCmp);
printf("\nSorted Args:\n");
for (i = 0; i < argc-1; i ){
printf("%s\n", arr[i]);
}
free (arr);
return 0;
}
int stringCmp(const void *str1, const void *str2)
{
return strlen(str1) - strlen(str2);
// return strcmp(*(char **)str1,*(char**) str2);
}
CodePudding user response:
As with the commented out call to strcmp
, the pointers received by the function actually have type char **
so you need to cast to that type.
return strlen(*(char **)str1) - strlen(*(char **)str2);
CodePudding user response:
It seems you need to allocate argc - 1
pointers instead of argc
pointers
char **arr = malloc( ( argc - 1 ) * sizeof(char *));
As for the comparison function then it can be defined the following way
int cmp( const void *s1, const void *s2 )
{
size_t n1 = strlen( *( const char ** )s1 );
size_t n2 = strlen( *( const char ** )s2 );
return ( n2 < n1 ) - ( n1 < n2 );
}
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp( const void *s1, const void *s2 )
{
size_t n1 = strlen( *( const char ** )s1 );
size_t n2 = strlen( *( const char ** )s2 );
return ( n2 < n1 ) - ( n1 < n2 );
}
int main(void)
{
char * s[] = { "12345", "1234", "123", "12", "1" };
const size_t N = sizeof( s ) / sizeof( *s );
for ( size_t i = 0; i < N; i )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
qsort( s, N, sizeof( *s ), cmp );
for ( size_t i = 0; i < N; i )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
}
The program output is
12345 1234 123 12 1
1 12 123 1234 12345
Pay attention to that to implements the comparison function like
return strlen(*(char **)str1) - strlen(*(char **)str2);
will be incorrect because values of an expression of the unsigned integer type size_t
can not be negative. And conversion such a value to the type int results in undefined behavior.