软件版本号的检查和比较是我们经常要用到的一个功能,我自己写了一个函数,用起来还是挺方便的。
// 函数功能:执行字符串形式的版本比较 // 返回值:比较成功返回真,比较失败返回假 // 比较结果保存到nResult中 // lpszVer1高于lpszVer2时nResult的值为1 // lpszVer1低于lpszVer2时nResult的值为-1 // lpszVer1等于lpszVer2时nResult的值为0 // 使用说明:安全的用法应当是先对函数返回值进行判断,返回为真时再检查nResult中的比较结果 BOOL CompareVersion(__in LPCTSTR lpszVer1, __in LPCTSTR lpszVer2, __out short & nResult) { // 参数安全性检查 if (lpszVer1 == NULL || lpszVer1[0] == _T('\0')) return FALSE; if (lpszVer2 == NULL || lpszVer2[0] == _T('\0')) return FALSE; // 参数有效性检查 for (size_t i = 0; i < _tcslen(lpszVer1); i++) { // 如果指定版本号中的当前字符在0到9范围以外,并且不是分割点,就认为是无效的 if ((lpszVer1[i] < _T('0') || lpszVer1[i] > _T('9')) && lpszVer1[i] != _T('.')) return FALSE; } for (size_t i = 0; i < _tcslen(lpszVer2); i++) { // 如果指定版本号中的当前字符在0到9范围以外,并且不是分割点,就认为是无效的 if ((lpszVer2[i] < _T('0') || lpszVer2[i] > _T('9')) && lpszVer2[i] != _T('.')) return FALSE; } // _tcstok_s函数会修改输入,所以先把版本字符串复制一份 // 根据版本号的通常表示法,不必根据源版本字符串的大小从堆上申请空间,直接定义即可满足绝大多数需求,也能提高效率 const short nMAX_VER_LEN = 64; TCHAR szVer1[nMAX_VER_LEN] = {0}, szVer2[nMAX_VER_LEN] = {0}; StringCchCopy(szVer1, nMAX_VER_LEN - 1, lpszVer1); StringCchCopy(szVer2, nMAX_VER_LEN - 1, lpszVer2); const TCHAR szSeps[] = _T("."); LPTSTR lpszToken1 = NULL, lpszToken2 = NULL; LPTSTR lpszNextToken1 = NULL, lpszNextToken2 = NULL; lpszToken1 = _tcstok_s(szVer1, szSeps, &lpszNextToken1); lpszToken2 = _tcstok_s(szVer2, szSeps, &lpszNextToken2); // 进行逐级拆分 while ((lpszToken1 != NULL) || (lpszToken2 != NULL)) { int nNum1 = 0, nNum2 = 0; // 检查拆分结果 if (lpszToken1 != NULL) { nNum1 = _tstoi(lpszToken1); lpszToken1 = _tcstok_s(NULL, szSeps, &lpszNextToken1); } if (lpszToken2 != NULL) { nNum2 = _tstoi(lpszToken2); lpszToken2 = _tcstok_s(NULL, szSeps, &lpszNextToken2); } // 执行比较 if (nNum1 > nNum2) { nResult = 1; break; } else if (nNum1 < nNum2) { nResult = -1; break; } else { nResult = 0; } } return TRUE; }
时间: 2024-11-05 23:35:57