1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
// base 10, entire string is parsed, no leading or trailing spaces, value representable as long long
bool is_integer( const char* cstr )
{
if( cstr == NULL || isspace( cstr[0] ) ) return false ;
// try to convert to an integer http://en.cppreference.com/w/cpp/string/byte/strtol
char* end = NULL ;
errno = 0 ;
strtoll( cstr, &end, 10 ) ;
return errno == 0 && *end == 0 ;
}
long long to_integer( const char* cstr ) { return strtoll( cstr, NULL, 10 ) ; }
// ascending on value of integer
int compare_integer( long long a, long long b ) { return (b<a) - (a<b) ; }
// comparison function which returns a negative integer value if the first argument is less than the second,
// a positive integer value if the first argument is greater than the second and zero if the arguments are equal.
// The signature of the comparison function should be equivalent to the following: int cmp(const void *a, const void *b);
// http://en.cppreference.com/w/c/algorithm/qsort
int compare( const void* aa, const void* bb )
{
const char* a = *(const char**)aa ;
const char* b = *(const char**)bb ;
if( is_integer(a) )
{
if( is_integer(b) ) return compare_integer( to_integer(a), to_integer(b) ) ;
else return -1 ; // integer strings s before non-integer strings
}
else
{
if( is_integer(b) ) return +1 ; // non-integer strings after integer strings
else return strcmp(a,b) ;
}
}
int main()
{
const char* a[] = { "-1", "potatoe", "-6", "zebra24", "+7", "violin", "-007", "vermilion", "7", "four", "+07" } ;
const size_t n = sizeof(a) / sizeof( a[0] ) ;
qsort( a, n, sizeof( a[0] ), compare ) ;
for( size_t i = 0 ; i < n ; ++i ) printf( "'%s'\n", a[i] ) ;
}
|