The following two functions define a method of comparing two strings. The method is similar to that implemented by strcmp, but differs in two ways. Whitespace within the strings is ignored, and numbers are compared numerically rather than character by character. ‘10′ is greater than ‘5′, for example.
/**
* Determines whether a character is whitespace or not.
*/
int iswhitespace(char x)
{
return x == ' ' || x == '\\n' || x == '\\r' || x == '\\t';
}
/**
* qsort comparison function for 'dictionary' like string sorting. Differs
* from strcmp in two important ways. 1) "Baby Zoe" comes after "Babyface",
* whitespace is ignored. 2) "5" comes before "10", numbers are sorted
* numerically.
*
* @param pStr1 Sort parameter 1. (ptr to char)
* @param pStr2 Sort parameter 2. (ptr to char)
* @return {-1, 0, 1} if pStr1 is {less than, equal to, greather than}
* pStr2.
*/
int dictionarySort(void* pStr1, void* pStr2)
{
char* a = pStr1;
char* b = pStr2;
for (;;)
{
if (*a == *b && *a == '\\0')
return 0;
else if (*a == '\\0')
return -1;
else if (*b == '\\0')
return 1;
while (iswhitespace(*a) && *a != '\\0') a++;
while (iswhitespace(*b) && *b != '\\0') b++;
if (*a >= '0' && *a <= '9' &&
*b >= '0' && *b <= '9')
{
/* a and b look to be pointing towards the start of numeric
* strings! :)
*/
int nNumericA = atoi(a);
int nNumericB = atoi(b);
if (nNumericA < nNumericB)
return -1;
else if (nNumericA > nNumericB)
return 1;
while (*a >= '0' && *a <= '9' && *a != '\\0') a++;
while (*b >= '0' && *b <= '9' && *b != '\\0') b++;
}
if (*a < *b)
return -1;
else if (*a > *b)
return 1;
a++;
b++;
}
/* shut off compiler warnings. */
return 0;
}