使用strtok在C中进行版本比较

时间:2017-03-29 08:18:34

标签: c string-comparison software-design strtok

我正在尝试编写一个 C程序比较2个软件版本号(格式为" 12.3.2"," 2.10"," 6.0.0.3"或" 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函数两次解析两个版本号。如果我能得到令牌并将它们作为整数返回,我稍后会使用比较函数来比较这些整数并解决这个问题。 我写了一个小程序来检查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编程语言很陌生,任何形式的帮助都会非常感激。

1 个答案:

答案 0 :(得分:2)

你可以使用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 != '\0' && *next_2 != '\0') {
        long x1 = strtol(v1, &next_1, 10);
        long x2 = strtol(v2, &next_2, 10);

        res = x1 - x2;
        if (res) {
            break;
        }

        if (*next_1 == '\0' || *next_2 == '\0') {
            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