| int CompareStrings(const void * lpv1, const void * lpv2)
{
TCHAR * sz1 = (TCHAR*) *(TCHAR**)lpv1;
TCHAR * sz2 = (TCHAR*) *(TCHAR**)lpv2;
int nPos1 = -1;
int nPos2 = -1;
int nEndPos1;
int nEndPos2;
int nResult;
while(true)
{
nPos1 ++;
nPos2 ++;
// Make sure we haven't hit the end of
// either of the strings
if (sz1[nPos1] == 0 && sz2[nPos2] == 0)
{
return 0;
}
else if (sz1[nPos1] == 0)
{
return -1;
}
else if (sz2[nPos2] == 0)
{
return 1;
}
// See if this part of both strings is a number
if (sz1[nPos1] >= _T('0') && sz1[nPos1] <= _T('9') &&
sz2[nPos2] >= _T('0') && sz2[nPos2] <= _T('9'))
{
// Find the end of each number
nEndPos1 = nPos1;
do
{
nEndPos1++;
} while (sz1[nEndPos1] >= _T('0') &&
sz1[nEndPos1] <= _T('9'));
nEndPos2 = nPos2;
do
{
nEndPos2++;
} while (sz2[nEndPos2] >= _T('0') &&
sz2[nEndPos2] <= _T('9'));
while (true)
{
if (nEndPos1 - nPos1 == nEndPos2 - nPos2)
{
// Both numbers are the same length, just
// compare them
nResult = _tcsnicmp(sz1 + nPos1, sz2 + nPos2,
nEndPos1 - nPos1);
if (nResult == 0)
{
nPos1 = nEndPos1 - 1;
nPos2 = nEndPos2 - 1;
break;
}
else
{
return nResult;
}
}
else if (nEndPos1 - nPos1 > nEndPos2 - nPos2)
{
// First number is longer, so if it's not zero
// padded, it's bigger
if (sz1[nPos1] == _T('0'))
{
nPos1 ++;
}
else
{
return 1;
}
}
else
{
// Second number is longer, so if it's not zero
// padded, it's bigger
if (sz2[nPos2] == _T('0'))
{
nPos2 ++;
}
else
{
return -1;
}
}
}
}
else
{
// One or both characters is not a number, so
// just compare them as a string
nResult = _tcsnicmp(sz1 + nPos1, sz2 + nPos2, 1);
if (nResult != 0)
{
return nResult;
}
}
}
}
|
| TCHAR * sz[] = {
"20 - Twenty",
"1 - One",
"10 - Ten (1)",
"2 - Two",
"20 - Twenty",
"15 - Fifteen",
"1 - One (b)",
"10 - Ten (2)",
"3 - Three",
"10 - Ten (100)",
};
qsort(sz,
sizeof(sz)/sizeof(TCHAR *),
sizeof(TCHAR *), CompareStrings);
for (int i = 0; i < sizeof(sz) / sizeof(TCHAR *); i ++)
{
printf("%s\n", sz[i]);
}
/*
Results:
1 - One
1 - One (b)
2 - Two
3 - Three
10 - Ten (1)
10 - Ten (2)
10 - Ten (100)
15 - Fifteen
20 - Twenty
20 - Twenty
*/
|