作者gn00618777 (非常念旧)
看板C_and_CPP
标题[问题] 版本字串比较
时间Mon Sep 28 23:19:07 2020
release 版本格式: x.x.xxx
目的 : 1.1.066 以及 1.1.66 ,程式都能认定同一版本。
(为了防止开发者少填1个0,也就是1.1.66)
(少填1个0,会使strncmp 1.1.66 > 1.1.066)
(我是觉得公司都已经规定格式了,1.1.66不就不被允许吗..)
(但上层总是想得比我们下面的人多拉~)
(所以我用了每小数点为分隔来求出每个数字来比)
(因此就能认定1.1.066 == 1.1.66了)
version 会存在既定 array(a_version, b_version)因为到时写成 fun传入来源指标
用strtok系列会改变来源位址,所以用a_version, b_version既定来存
char a_version[] = "1.1.066";
char b_version[] = "1.1.66";
char *a_ptr = NULL;
char *b_ptr = NULL;
char *p,*q;
int i = 0;
int result = 0;
p = strtok_r(a_version, ".", &a_ptr);
q = strtok_r(b_version, ".", &b_ptr);
while(p != NULL && q != NULL) {
if((int)strtoul(p, NULL, 10) > (int)strtoul(q, NULL, 10)) {
result = 1;
break;
} else if((int)strtoul(p, NULL, 10) < (int)strtoul(q, NULL, 10)) {
result = -1;
break;
} else {
//do nothing
}
p = strtok_r(NULL, ".", &a_ptr);
q = strtok_r(NULL, ".", &b_ptr);
}
return result; //1: a>b -1:a<b 0: a==b
请问神人们还有没有更漂亮的写法呢? 例如只用一个既定array之类的?
感谢指教
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.171.134.9 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1601306354.A.E12.html
※ 编辑: gn00618777 (1.171.134.9 台湾), 09/28/2020 23:44:33
1F:→ Lipraxde: 写成状态机一个个 char 比过去? 09/28 23:54
2F:→ Lipraxde: 怎麽写其实没差啦,不过这种东西可能要多加些注解,不 09/28 23:56
3F:→ Lipraxde: 然看起来像是在搞 obfuscation... 09/28 23:56
4F:推 kingofsdtw: 丢git check sum 09/29 00:07
5F:→ encorek22554: 可以参考leetcode.165 09/29 01:34
6F:推 LPH66: 你其实可以在 while 回圈里用两个变数暂存两个部份的数字 09/29 04:42
7F:→ LPH66: 这样同样的呼叫不用重覆进行; 因为这种东西编译器很难知道 09/29 04:43
8F:→ LPH66: 你这两次呼叫其实是同一个东西 09/29 04:43
9F:→ loveme00835: 为了比较字串内容, 对字串内容做了什麽事你知道吗? 09/29 09:04
10F:推 appleway: sscanf(v_str, “%d.%d.%d”, &major, &minor, &post); 09/29 15:39
11F:→ gn00618777: 回Liprx大,你一个一个char去比较,那还未parse到'.' 09/29 22:25
12F:→ gn00618777: 到的char该存到哪? 09/29 22:25
13F:→ gn00618777: 回LPH66大,用两个变数去存? 请问你是一个一个char 09/29 22:27
14F:→ gn00618777: 去parse吗? 还是一样用strtok 呢? 09/29 22:28
15F:→ gn00618777: 回loveme大,字串的. 会被替换成\n 09/29 22:29
16F:→ gn00618777: 回appleway大,你这方法满酷的,但要是不只两个小数点 09/29 22:30
17F:→ gn00618777: 就无法比完全部了 09/29 22:30
18F:→ petercoin: apple大应该是因为你们的规定所以写这样给你啦,如果 09/29 23:03
19F:→ petercoin: 有三个小数点就写三次阿。不然就用“.”来split之後看 09/29 23:03
20F:→ petercoin: 阵列长度有多少再转成数字比对也行 09/29 23:03
22F:→ loveme00835: 考虑到字串长度格式还有比较方式的不同, 写成可客制 09/29 23:15
23F:→ loveme00835: 化复用性会高一些 09/29 23:15
24F:→ Lipraxde: 不懂要存什麽。应该有两个 char* 指到当下比到哪就可以 09/29 23:54
25F:→ Lipraxde: 了吧? 09/29 23:54
26F:→ Lipraxde: 仔细想想好像也不用状态机 @@ 09/29 23:54
27F:推 LPH66: 我说的是 strtoul 的呼叫结果 09/30 16:34
28F:→ gn00618777: 不解........... 我废= = 09/30 23:12
29F:→ gn00618777: 你是说只要 if else 对不对 09/30 23:15
30F:→ gn00618777: 阿我知道了,参考strcmp source code 他只要相减 09/30 23:16
31F:→ gn00618777: return strtoul(a) - strtoul(b) 就可以了 09/30 23:16
32F:推 LPH66: OK, 我再讲清楚一点好了: 10/01 01:21
33F:→ LPH66: int v1 = strtol(...); int v2 = strtol(...); 10/01 01:22
34F:→ LPH66: if(v1 > v2) {...} else if(v1 < v2) {...} else {...} 10/01 01:22
35F:→ LPH66: 你同一个函数写两次很有可能实际上就呼叫两次 10/01 01:23
36F:→ LPH66: 至於 return 相减结果这个写法你再仔细考虑清楚一次 10/01 01:24
37F:→ LPH66: 不是说你错, 但你要仔细确定有没有漏掉的地方 10/01 01:24
38F:→ gn00618777: 欧欧 的确不用再strtoul。至於第二点我的确也少考虑 10/02 09:07
39F:→ gn00618777: 少考虑了当某一个为NULL而另个为非NULL的情况 10/02 09:08
40F:→ gn00618777: 回encorek22554大,感谢你提供的资讯 10/02 09:22