[問題] 版本字串比較

作者: gn00618777 (非常念舊)   2020-09-28 23:19:07
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之類的?
感謝指教
作者: Lipraxde (Lipraxde)   2020-09-28 23:54:00
寫成狀態機一個個 char 比過去?怎麼寫其實沒差啦,不過這種東西可能要多加些註解,不然看起來像是在搞 obfuscation...
作者: kingofsdtw (不能閒下來!!)   2020-09-29 00:07:00
丟git check sum
作者: encorek22554 (二寶)   2020-09-29 01:34:00
可以參考leetcode.165
作者: LPH66 (-6.2598534e+18f)   2020-09-29 04:42:00
你其實可以在 while 迴圈裡用兩個變數暫存兩個部份的數字這樣同樣的呼叫不用重覆進行; 因為這種東西編譯器很難知道你這兩次呼叫其實是同一個東西
作者: loveme00835 (髮箍)   2020-09-29 09:04:00
為了比較字串內容, 對字串內容做了什麼事你知道嗎?
作者: appleway (蘋果愛天空)   2020-09-29 15:39:00
sscanf(v_str, “%d.%d.%d”, &major, &minor, &post);
作者: gn00618777 (非常念舊)   2020-09-29 22:25:00
回Liprx大,你一個一個char去比較,那還未parse到'.'到的char該存到哪?回LPH66大,用兩個變數去存? 請問你是一個一個char去parse嗎? 還是一樣用strtok 呢?回loveme大,字串的. 會被替換成\n回appleway大,你這方法滿酷的,但要是不只兩個小數點就無法比完全部了
作者: petercoin (彼得幣)   2020-09-29 23:03:00
apple大應該是因為你們的規定所以寫這樣給你啦,如果有三個小數點就寫三次阿。不然就用“.”來split之後看陣列長度有多少再轉成數字比對也行
作者: loveme00835 (髮箍)   2020-09-29 23:14:00
不太會 C, 不過大概就像醬 https://bit.ly/36hfTvS考慮到字串長度格式還有比較方式的不同, 寫成可客製化複用性會高一些
作者: Lipraxde (Lipraxde)   2020-09-29 23:54:00
不懂要存什麼。應該有兩個 char* 指到當下比到哪就可以了吧?仔細想想好像也不用狀態機 @@
作者: LPH66 (-6.2598534e+18f)   2020-09-30 16:34:00
我說的是 strtoul 的呼叫結果
作者: gn00618777 (非常念舊)   2020-09-30 23:12:00
不解........... 我廢= =你是說只要 if else 對不對阿我知道了,參考strcmp source code 他只要相減return strtoul(a) - strtoul(b) 就可以了
作者: LPH66 (-6.2598534e+18f)   2020-10-01 01:21:00
OK, 我再講清楚一點好了:int v1 = strtol(...); int v2 = strtol(...);if(v1 > v2) {...} else if(v1 < v2) {...} else {...}你同一個函數寫兩次很有可能實際上就呼叫兩次至於 return 相減結果這個寫法你再仔細考慮清楚一次不是說你錯, 但你要仔細確定有沒有漏掉的地方
作者: gn00618777 (非常念舊)   2020-10-02 09:07:00
歐歐 的確不用再strtoul。至於第二點我的確也少考慮少考慮了當某一個為NULL而另個為非NULL的情況回encorek22554大,感謝你提供的資訊

Links booklink

Contact Us: admin [ a t ] ucptt.com