hi, i am writing an application that receives data with items and version numbers. The numbers are formatted like 1.0.1 or 1.2.5. How can i compare these version numbers. I think they have to be formatted as a string first, no? If so, what option do i have to having objective C understand the 1.2.5 is newer than 1.0.1?
A:
This question, while not identical to yours, offers insights on how you could accomplish what you're asking.
Ben Gottlieb
2009-12-30 04:42:37
thanks...i think this will be perfect
mlecho
2009-12-30 05:50:29
A:
If you know each version number will have exactly 3 integers separated by dots, you can parse them (e.g. using sscanf(3)
) and compare them:
const char *version1str = "1.0.1";
const char *version2str = "1.2.5";
int major1, minor1, patch1;
int major2, minor2, patch2;
if(sscanf(version1str, "%d.%d.%d", &major1, &minor1, &patch1) == 3 &&
sscanf(version2str, "%d.%d.%d", &major2, &minor2, &patch2) == 3)
{
// Parsing succeeded, now compare the integers
if(major1 > major2 ||
(major1 == major2 && (minor1 > minor2 ||
(minor1 == minor2 && patch1 > patch2))))
{
// version1 > version2
}
else if(major1 == major2 && minor1 == minor2 && patch1 == patch2)
{
// version1 == version2
}
else
{
// version2 < version2
}
}
else
{
// Handle error, parsing failed
}
Adam Rosenfield
2009-12-30 05:15:49
A:
Glibc has a function strverscmp
and versionsort
… unfortunately, not portable to the iPhone, but you can write your own fairly easily. This (untested) re-implementation comes from just reading the documented behavior, and not from reading Glibc's source code.
int strverscmp(const char *s1, const char *s2) {
const char *b1 = s1, *b2 = s2, *e1, *e2;
long n1, n2;
size_t z1, z2;
while (*b1 && *b1 == *b2) b1++, b2++;
if (!*b1 && !*b2) return 0;
e1 = b1, e2 = b2;
while (b1 > s1 && isdigit(b1[-1])) b1--;
while (b2 > s2 && isdigit(b2[-1])) b2--;
n1 = strtol(b1, &e1, 10);
n2 = strtol(b2, &e2, 10);
if (b1 == e1 || b2 == e2) return strcmp(s1, s2);
if (n1 < n2) return -1;
if (n1 > n2) return 1;
z1 = strspn(b1, "0"), z2 = strspn(b2, "0");
if (z1 > z2) return -1;
if (z1 < z2) return 1;
return 0;
}
ephemient
2009-12-30 05:47:54
+3
A:
This is the simplest way to compare versions, keeping in mind that "1" < "1.0" < "1.0.0":
NSString* requiredVersion = @"1.2.0";
NSString* actualVersion = @"1.1.5";
if ([requiredVersion compare:actualVersion options:NSNumericSearch] == NSOrderedDescending) {
// actualVersion is lower than the requiredVersion
}
Nathan de Vries
2010-01-02 07:11:40
+1
A:
Sparkle (a framework for MacOS) has a SUVersionComparator class that does this.
uliwitness
2010-01-03 15:54:55