在c++中进行不区分大小写字符串比较而不将字符串转换为全大写或全小写的最佳方法是什么?

请指出这些方法是否对unicode友好,以及它们的可移植性如何。


当前回答

str1.size() == str2.size() && std::equal(str1.begin(), str1.end(), str2.begin(), [](auto a, auto b){return std::tolower(a)==std::tolower(b);})

如果你不能使用boost,你可以在c++ 14中使用上面的代码。对于宽字符,必须使用std::towlower。

其他回答

Boost包含一个方便的算法:

#include <boost/algorithm/string.hpp>
// Or, for fewer header dependencies:
//#include <boost/algorithm/string/predicate.hpp>

std::string str1 = "hello, world!";
std::string str2 = "HELLO, WORLD!";

if (boost::iequals(str1, str2))
{
    // Strings are identical
}

可以在Unix上使用strcasecmp,在Windows上使用stricmp。

到目前为止还没有提到的一件事是,如果您使用这些方法使用stl字符串,首先比较两个字符串的长度是有用的,因为这个信息已经在string类中提供给您了。如果您正在比较的两个字符串的长度一开始就不相同,这可以防止进行代价高昂的字符串比较。

你说的是一个愚蠢的不区分大小写的比较还是一个完全标准化的Unicode比较?

哑比较不会找到可能相同但二进制不相等的字符串。

例子:

U212B (ANGSTROM SIGN)
U0041 (LATIN CAPITAL LETTER A) + U030A (COMBINING RING ABOVE)
U00C5 (LATIN CAPITAL LETTER A WITH RING ABOVE).

都是等价的,但它们也有不同的二进制表示。

也就是说,Unicode标准化应该是必读的,特别是如果您计划支持韩文,Thaï和其他亚洲语言。

此外,IBM几乎为大多数优化的Unicode算法申请了专利,并将它们公开提供。它们还维护一个实现:IBM ICU

在c++中比较两个字符串的一个简单方法是使用_stricmp

// Case insensitive (could use equivalent _stricmp)  
result = _stricmp( string1, string2 );  

如果你想使用std::string,一个例子:

std::string s1 = string("Hello");
if ( _stricmp(s1.c_str(), "HELLO") == 0)
   std::cout << "The string are equals.";

更多信息请访问:https://msdn.microsoft.com/it-it/library/e0z9k731.aspx

不使用Boost可以通过使用c_str()获取C字符串指针并使用strcasecmp来实现:

std::string str1 ="aBcD";
std::string str2 = "AbCd";;
if (strcasecmp(str1.c_str(), str2.c_str()) == 0)
{
    //case insensitive equal 
}