如何正确使用strtok进行版本比较?
How to use strtok properly to compare versions?
我正在尝试编写一个 C 程序,它比较 2 个软件版本号(格式为“12.3.2”,“ 2.10", "6.0.0.3" or "2.0") 在 C 中使用 strtok。1.0 也被认为大于 1. 所以,基本上, 比较代表版本号的 2 个字符串。试图找出代码工作的方法。我被困在如何存储这些令牌的地步?然后我以后怎么比较它们?
所以如果:
v1>v2 : return 1,
v1==v2:return 0
v1<v2: return -1.
函数签名可以是:
int cmp(char *v1, char *v2){...}
(v1 和 v2 是版本号。)
有什么建议么?与 Python 或其他面向对象的编程语言(C#,java)相比,我实际上是 C 的新手。
这是我目前尝试过的方法:
struct version_t {
int major;
int minor;
int build;
};
version_t parse_ver(const char* version_str) {
version_t res;
version_t r;
// Trying to use strtok_r to split the string, and atoi to convert
//tokens to ints
char *token;
char *rest = version_str;
while((token = strtok_r(rest,".",&rest)))
{
res = token;
}
r = atoi(res);
return r;
}
最初我只是考虑版本格式为 12.3.4(3 个字段)。我不确定如何使用其他类型的版本号,例如 1.34.2.5 或 1.0
然后我会使用 parse_ver 函数两次来解析两个版本号。如果我能得到令牌并将它们 return 作为整数,我稍后会使用比较函数来比较这些整数并解决这个问题。
我写了一个小程序来检查 strtok 是如何工作的,我通过编写如下内容得到了这个想法:
void main(void)
{
char str[] = "1.2.3.4";
char *token;
char *rest = str;
while((token = strtok_r(rest, ".", &rest)))
{
printf("token:%s\n", token);
}
}
但我需要以某种方式将令牌存储在结构中。这里有点迷糊。
同样,我对 C 编程语言还很陌生,非常感谢任何类型的帮助。
您可以为此使用 strtol()
,利用尾指针并跳过小数点。这将允许比较每个字段。
在下面的代码中,从第一个字段开始,如果第一个版本号大于第二个则返回正值,如果第一个版本号小于第二个则返回负值。如果两个版本号相等,则跳过小数点,比较接下来的两个字段。如果到达一个字符串的末尾并且字段比较相等,则返回尾指针指示的值之间的差异(因此 1.0
大于 1
)。
#include <stdio.h>
#include <stdlib.h>
int ver_comp(char *, char *);
int main(void)
{
char *ver1 = "12.3.2";
char *ver2 = "2.10";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
ver1 = "2.10";
ver2 = "6.0.0.3";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
ver1 = "2";
ver2 = "2.0";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
ver1 = "2.0.0.1.2";
ver2 = "2.0.0.2.2";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
ver1 = "1.2.3.4";
ver2 = "1.2.3.4";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
return 0;
}
int ver_comp(char *v1, char *v2)
{
int res = 0;
char *next_1 = v1;
char *next_2 = v2;
while (*next_1 != '[=10=]' && *next_2 != '[=10=]') {
long x1 = strtol(v1, &next_1, 10);
long x2 = strtol(v2, &next_2, 10);
res = x1 - x2;
if (res) {
break;
}
if (*next_1 == '[=10=]' || *next_2 == '[=10=]') {
res = *next_1 - *next_2;
break;
}
v1 = next_1 + 1;
v2 = next_2 + 1;
}
return res;
}
程序输出:
12.3.2 - 2.10 = 10
2.10 - 6.0.0.3 = -4
2 - 2.0 = -46
2.0.0.1.2 - 2.0.0.2.2 = -1
1.2.3.4 - 1.2.3.4 = 0
我正在尝试编写一个 C 程序,它比较 2 个软件版本号(格式为“12.3.2”,“ 2.10", "6.0.0.3" or "2.0") 在 C 中使用 strtok。1.0 也被认为大于 1. 所以,基本上, 比较代表版本号的 2 个字符串。试图找出代码工作的方法。我被困在如何存储这些令牌的地步?然后我以后怎么比较它们? 所以如果:
v1>v2 : return 1,
v1==v2:return 0
v1<v2: return -1.
函数签名可以是:
int cmp(char *v1, char *v2){...}
(v1 和 v2 是版本号。) 有什么建议么?与 Python 或其他面向对象的编程语言(C#,java)相比,我实际上是 C 的新手。
这是我目前尝试过的方法:
struct version_t {
int major;
int minor;
int build;
};
version_t parse_ver(const char* version_str) {
version_t res;
version_t r;
// Trying to use strtok_r to split the string, and atoi to convert
//tokens to ints
char *token;
char *rest = version_str;
while((token = strtok_r(rest,".",&rest)))
{
res = token;
}
r = atoi(res);
return r;
}
最初我只是考虑版本格式为 12.3.4(3 个字段)。我不确定如何使用其他类型的版本号,例如 1.34.2.5 或 1.0
然后我会使用 parse_ver 函数两次来解析两个版本号。如果我能得到令牌并将它们 return 作为整数,我稍后会使用比较函数来比较这些整数并解决这个问题。 我写了一个小程序来检查 strtok 是如何工作的,我通过编写如下内容得到了这个想法:
void main(void)
{
char str[] = "1.2.3.4";
char *token;
char *rest = str;
while((token = strtok_r(rest, ".", &rest)))
{
printf("token:%s\n", token);
}
}
但我需要以某种方式将令牌存储在结构中。这里有点迷糊。
同样,我对 C 编程语言还很陌生,非常感谢任何类型的帮助。
您可以为此使用 strtol()
,利用尾指针并跳过小数点。这将允许比较每个字段。
在下面的代码中,从第一个字段开始,如果第一个版本号大于第二个则返回正值,如果第一个版本号小于第二个则返回负值。如果两个版本号相等,则跳过小数点,比较接下来的两个字段。如果到达一个字符串的末尾并且字段比较相等,则返回尾指针指示的值之间的差异(因此 1.0
大于 1
)。
#include <stdio.h>
#include <stdlib.h>
int ver_comp(char *, char *);
int main(void)
{
char *ver1 = "12.3.2";
char *ver2 = "2.10";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
ver1 = "2.10";
ver2 = "6.0.0.3";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
ver1 = "2";
ver2 = "2.0";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
ver1 = "2.0.0.1.2";
ver2 = "2.0.0.2.2";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
ver1 = "1.2.3.4";
ver2 = "1.2.3.4";
printf("%s - %s = %d\n", ver1, ver2, ver_comp(ver1, ver2));
return 0;
}
int ver_comp(char *v1, char *v2)
{
int res = 0;
char *next_1 = v1;
char *next_2 = v2;
while (*next_1 != '[=10=]' && *next_2 != '[=10=]') {
long x1 = strtol(v1, &next_1, 10);
long x2 = strtol(v2, &next_2, 10);
res = x1 - x2;
if (res) {
break;
}
if (*next_1 == '[=10=]' || *next_2 == '[=10=]') {
res = *next_1 - *next_2;
break;
}
v1 = next_1 + 1;
v2 = next_2 + 1;
}
return res;
}
程序输出:
12.3.2 - 2.10 = 10
2.10 - 6.0.0.3 = -4
2 - 2.0 = -46
2.0.0.1.2 - 2.0.0.2.2 = -1
1.2.3.4 - 1.2.3.4 = 0