忽略大小写字符串的比较这看起来是一个简单的问题。说容易也容易,说困难也困难,具体取决于你所要求的通用性怎么样,如果你不打算考虑国际化的问题,如果是类似于strcmp之类的功能那实现起来还算简单,如果需要考虑的话下面有几种简单的方法。下面的几种方法是我在effective STL中找到的,现在我把它们做一个总结。
方法一:使用STL的mismatch算法
<span style="font-size:18px;">int CompareChar(char c1,char c2)
{
int iC1 = tolower(static_cast<unsigned char>(c1));
int iC2 = tolower(static_cast<unsigned char>(c2));
if(iC1 < iC2)
return -1;
if(iC1 > iC2)
return 1;
return 0;
}
</span>
tolower函数的参数和返回值都是int但是除非该int是EOF,否则他的值必须可以用unsiged int来表示,在C和C++中char有可能是有符号的也有可能是无符号的,所以确定char是无符号的唯一办法是进行强制的转换,而且这也解释了为什么用int而不是用char来保存tolower的返回值了。
<span style="font-size:18px;">int CompareStringImpl(const string& s1,const string& s2);
int CompareString(const string& s1,const string& s2)
{
if(s1.size() <= s2.size())
return CompareStringImpl(s1,s2);
else
return -CompareStringImpl(s2,s1);
}
int CompareStringImpl(const string& s1,const string& s2)
{
typedef pair<string::const_iterator,string::const_iterator>PSCI;
PSCI p = mismatch(s1.begin(),s1.end(),s2.begin(),not2(ptr_fun(CompareChar)));
if(p.first == s1.end())
{
if(p.second == s2.end())
return 0;
else
return -1;
}
return CompareChar(*p.first,*p.second);
}
</span>
方法二:使用STL的lexicographical_compare算法
<span style="font-size:18px;">bool CharCompare(char c1,char c2)
{
return (tolower(static_cast<unsigned char>(c1)) < tolower(static_cast<unsigned char>(c2)));
}
bool StringCompare(const string& s1,const string& s2)
{
return !lexicographical_compare(s1.begin(),s1.end(),s2.begin(),s2.end(),CharCompare);
}
</span>
以上的方法在windows,Linux下都是通用的。
如果在windows平台下你不用考虑国际化的问题,并且你知道你的字符串中不会包含内嵌的空字符串,而且你不在乎移植性那么你可以用最简单的一种方式:
int CStringCompare(const string&s1,const string& s2)
{
return stricmp(s1.c_str(),s2.c_str());
}
就效率上说这个方法的效率确实要比前两个方法的效率要高。