M
Malcolm
Ever noticed when looking at a list of computer-sorted items that you get
entries like
aardvark
aardvark1
aardvark10
aardvark2
....
This is because the sorting program is calling strcmp() internally.
Here's a replacement that solves this problem.
int compstr(const char *s1, const char *s2)
{
long n1, n2;
char *end1, *end2;
while(*s1 && *s2)
{
if(isdigit(*s1))
{
if(isdigit(*s2))
{
n1 = strtol(s1, &end1, 10);
n2 = strtol(s2, &end2, 10);
if(n1 < n2)
return -1;
if(n1 > n2)
return 1;
s1 = end1;
s2 = end2;
}
else
return *s1 - *s2;
}
else if(*s1 == *s2)
{
s1++;
s2++;
}
else
return *s1 - *s2;
}
if(*s2)
return -1;
if(*s1)
return 1;
return 0;
}
A few issues remain. For instance, this function only works in ANSI or other
lexigraphically-ordered character set.
Also
aardvark1
and
aardvark001
will compare as equal.
Also it doesn't understnad decimal points. I don't know if this is an
advantage or not. In books you will commonly find figures labelled
fig1.1 ... fig1.9 fig1.10
on the other hand, 1.10 is lower than 1.9 in the decimal system.
entries like
aardvark
aardvark1
aardvark10
aardvark2
....
This is because the sorting program is calling strcmp() internally.
Here's a replacement that solves this problem.
int compstr(const char *s1, const char *s2)
{
long n1, n2;
char *end1, *end2;
while(*s1 && *s2)
{
if(isdigit(*s1))
{
if(isdigit(*s2))
{
n1 = strtol(s1, &end1, 10);
n2 = strtol(s2, &end2, 10);
if(n1 < n2)
return -1;
if(n1 > n2)
return 1;
s1 = end1;
s2 = end2;
}
else
return *s1 - *s2;
}
else if(*s1 == *s2)
{
s1++;
s2++;
}
else
return *s1 - *s2;
}
if(*s2)
return -1;
if(*s1)
return 1;
return 0;
}
A few issues remain. For instance, this function only works in ANSI or other
lexigraphically-ordered character set.
Also
aardvark1
and
aardvark001
will compare as equal.
Also it doesn't understnad decimal points. I don't know if this is an
advantage or not. In books you will commonly find figures labelled
fig1.1 ... fig1.9 fig1.10
on the other hand, 1.10 is lower than 1.9 in the decimal system.