Следующая процедура сравнивает строки номеров версий, состоящие из подлинных номеров. Преимущество в том, что разделитель не имеет значения; он будет работать, например, с 141.01.03, 141: 1: 3 или даже 141A1P3. Он также обрабатывает несовпадающие хвосты, так что 141.1.3 предшествует 141.1.3.1.
#include <assert.h>
#include <stdlib.h>
int versionCmp( char *pc1, char *pc2)
{
int result = 0;
/* loop through each level of the version string */
while (result == 0) {
/* extract leading version numbers */
char* tail1;
char* tail2;
unsigned long ver1 = strtoul( pc1, &tail1, 10 );
unsigned long ver2 = strtoul( pc2, &tail2, 10 );
/* if numbers differ, then set the result */
if (ver1 < ver2)
result = -1;
else if (ver1 > ver2)
result = +1;
else {
/* if numbers are the same, go to next level */
pc1 = tail1;
pc2 = tail2;
/* if we reach the end of both, then they are identical */
if (*pc1 == '\0' && *pc2 == '\0')
break;
/* if we reach the end of one only, it is the smaller */
else if (*pc1 == '\0')
result = -1;
else if (*pc2 == '\0')
result = +1;
/* not at end ... so far they match so keep going */
else {
pc1++;
pc2++;
}
}
}
return result;
}
int main( void )
{
assert(versionCmp("1.2.3" , "1.2.3" ) == 0);
assert(versionCmp("1.2.3" , "1.2.4" ) < 0);
assert(versionCmp("1.2.4" , "1.2.3" ) > 0);
assert(versionCmp("10.2.4", "9.2.3" ) > 0);
assert(versionCmp("9.2.4", "10.2.3") < 0);
/* Trailing 0 ignored. */
assert(versionCmp("01", "1") == 0);
/* Any single space delimiter is OK. */
assert(versionCmp("1a2", "1b2") == 0);
return EXIT_SUCCESS;
}
Замените strtoul
s на strcspn
s и strncmp
, и вы можете использовать его для сравнения нечисловых "номеров" версий, но разделителем должна быть точка. Например, 141.3A.1 сортирует до 141.3B.
...
while (result == 0) {
/* ignore leading zeroes */
pc1 += strspn( pc1, "0" );
pc2 += strspn( pc2, "0" );
/* extract leading version strings */
int len1 = strcspn( pc1, "." );
int len2 = strcspn( pc2, "." );
/* if one is shorter than the other, it is the smaller version */
result = len1 - len2;
/* if the same length then compare as strings */
if (result == 0)
result = strncmp( pc1, pc2, len1 );
if (result == 0) {
pc1 += len1;
pc2 += len2;
if (*pc1 == '\0' && *pc == '\0')
...
person
Peter Raynham
schedule
25.02.2013
strcmp
:-) - person cnicutar   schedule 25.02.2013