字符串逻辑比较函数---StrCmpLogicalW的模拟实现

本文介绍了一个模仿Windows API中的StrCmpLogicalW函数的实现方式,该函数能够根据数字的数值大小而非文本顺序来进行字符串比较。通过示例代码展示了如何利用正则表达式来识别并比较字符串中的数字,从而实现逻辑排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们最熟悉的字符串比较函数莫过于 strcmp 了,但这个函数仅仅是根据字符进行比较,没有考虑字符串的逻辑意义,为此微软为我们提供了一个 StrCmpLogicalW 函数,它比较数字时不将其视为文本而是视为数值。

我们可以从下列这个简单的字符串数组排序的结果看出这两个函数的区别:

使用StrCmpLogicalW进行比较的结果:

2string
3string
20string
st2ring
st3ring
st20ring
string2
string3
string20
使用简单的 strcmp 函数进行比较的结果:

20string
2string
3string
st20ring
st2ring
st3ring
string2
string20
string3

下面这段代码就是模仿这个函数的实现:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> #include < iostream >
#include
< afx.h >
#include
" deelx.h "
using namespace std;

#define MATCH_NUMBERS"[+-]?//d+(//.//d+)?"


int Compare(CStringcsText1,CStringcsText2)
{
staticCRegexpreg(MATCH_NUMBERS);
intnEnd1=0,nEnd2=0;

while(1)
{
MatchResultret1
=reg.Match(csText1,nEnd1);
MatchResultret2
=reg.Match(csText2,nEnd2);

CString
const&csSubText1=ret1.IsMatched()?csText1.Mid(nEnd1,ret1.GetStart()-nEnd1):csText1;
CString
const&csSubText2=ret2.IsMatched()?csText2.Mid(nEnd2,ret2.GetStart()-nEnd2):csText2;

//子串不同,则返回
if(csSubText1!=csSubText2)
returncsSubText1>csSubText2?1:-1;

/**//*
既然两个字符串相等,而两个字符串又已经消耗完,那自然可以返回了.
*/

if(!ret1.IsMatched()&&!ret2.IsMatched())return0;

if(ret1.IsMatched()&&ret2.IsMatched())
{//字符串还未消耗完毕,继续按逻辑比较
/**//*
GetGroupStart()返回正则表达式中"(//.//d+)"这一个组的起始位置.如果没有匹配,则返回-1;(可查看deelx的说明文档)
这个组是否匹配意味着捕获的数字是否带有小数点以及小数部分.
如果捕获的两个数字有一个带有小数部分.则按浮点数处理.否则按整数处理
*/

if(ret1.GetGroupStart(1)>=0||ret2.GetGroupStart(1)>=0)
{//带小数点,按浮点数比较数值大小
doubledNum1=_tcstod(csText1.Mid(ret1.GetStart(),ret1.GetEnd()-ret1.GetStart()),0);
doubledNum2=_tcstod(csText2.Mid(ret2.GetStart(),ret2.GetEnd()-ret2.GetStart()),0);
if(dNum1!=dNum2)returndNum1>dNum2?1:-1;
}

else
{//按整数处理,比较两个数的数值大小
__int64nNum1=_ttoi64(csText1.Mid(ret1.GetStart(),ret1.GetEnd()-ret1.GetStart()));
__int64nNum2
=_ttoi64(csText2.Mid(ret2.GetStart(),ret2.GetEnd()-ret2.GetStart()));
if(nNum1!=nNum2)returnnNum1>nNum2?1:-1;
}


nEnd1
=ret1.GetEnd();
nEnd2
=ret2.GetEnd();
}

else
{//现在两个里面肯定有且只有一个IsMatch()不为真
returnret1.IsMatched()?1:-1;
}

}

return0;
}


int main()
{
CStringstr1(
"st3ring"),str2("st20ring");
intresult;
result
=Compare(str1,str2);
std::cout
<<"resultis:"<<result<<endl;
result
=strcmp(str1.GetBuffer(10),str2.GetBuffer(10));
cout
<<"resultis:"<<result<<endl;
system(
"pause");
return0;
}

代码中使用了一个开源的正则表达式引擎,DEELX 正则表达式引擎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值