【问题标题】:Comparing wstring with ignoring the case比较 wstring 和忽略大小写
【发布时间】:2010-11-07 06:38:11
【问题描述】:

我敢肯定这之前会被问到但找不到。是否有任何内置方式(即使用 std::wstring 的方法或算法)对两个 wstring 对象进行不区分大小写的比较?

【问题讨论】:

  • 请注意,不区分大小写的比较取决于区域设置。
  • stackoverflow.com/questions/11635/… ,我推荐 Boost 解决方案或提取 c_str 并使用 wcscasecmp/_wcsicmp
  • @Hasturkun:感谢您的链接。我依稀记得在 SO 上读过这篇文章。

标签: c++ string unicode stl


【解决方案1】:

您可以使用std::tolower() 将字符串转换为小写或使用函数wcscasecmpc_str() 进行不区分大小写的比较。

这是一个你也可以直接使用的比较函子:

struct ci_less_w
{
  bool operator() (const std::wstring & s1, const std::wstring & s2) const
  {
      #ifndef _WIN32
            return wcscasecmp(s1.c_str(), s2.c_str()) < 0;
      #else
            return _wcsicmp(s1.c_str(), s2.c_str()) < 0;
      #endif
  }
};

【讨论】:

  • 我认为需要一个标准库解决方案。
【解决方案2】:

如果您不介意与 Microsoft 实现绑定,您可以使用在 &lt;string.h&gt; 中定义的此函数

int _wcsnicmp(
   const wchar_t *string1,
   const wchar_t *string2,
   size_t count 
);

但是,如果您想要最佳的性能/兼容性/功能比,您可能必须查看 boost 库(无论如何,它的一部分是 stl)。简单示例(取自different answer 到不同的问题):

#include <boost/algorithm/string.hpp>

std::wstring wstr1 = L"hello, world!";
std::wstring wstr2 = L"HELLO, WORLD!";

if (boost::iequals(wstr1, wstr2))
{
    // Strings are identical
}

【讨论】:

  • 字符串文字中缺少 L 编码前缀
【解决方案3】:

使用标准库:

bool comparei(wstring stringA , wstring stringB)
{
    transform(stringA.begin(), stringA.end(), stringA.begin(), toupper);
    transform(stringB.begin(), stringB.end(), stringB.begin(), toupper);

    return (stringA == stringB);
}

wstring stringA = "foo";
wstring stringB = "FOO";
if(comparei(stringA , stringB))
{
    // strings match
}

【讨论】:

  • if(stringA == stringB) 迫使我发表评论! :) 应该返回 (stringA == stringB)
  • 当您转换为大写然后返回不同的字符串时,此解决方案不适用于多种语言环境,在某些语言中。
  • 您不只是比较字符串,实际上无论结果如何,您都将两个字符串都设为大写。尝试写一个签名为bool compare(const wstring stringA, const wstring stringB)的方法,然后修复这个算法。
  • 应该用过towupper。
【解决方案4】:

如果您需要字符串始终进行不区分大小写的比较(使用运算符 == 或 != 时),那么一个可能的优雅解决方案是重新定义 char_traits::compare 方法。

定义您自己的结构。示例

struct my_wchar_traits: public std::char_traits< wchar_t>
{
    static int compare( const char_type* op1, const char_type* op2, std::size_t num) 
    {
       // Implementation here... any of the previous responses might help...
    } 
};

然后,定义你自己的不区分大小写的字符串:

typedef std::basic_string< wchar_t, my_wchar_traits> my_wstring;

【讨论】:

    【解决方案5】:

    说英语对吧?!虽然我会选择我可爱的 ​​Boost :)

    bool isequal(const std::wstring& first, const std::wstring& second)
    {
        if(first.size() != second.size())
            return false;
    
        for(std::wstring::size_type i = 0; i < first.size(); i++)
        {
            if(first[i] != second[i] && first[i] != (second[i] ^ 32))
                return false;
        }
    
        return true;
    }
    

    【讨论】:

    • +1。 (second[i] ^ 32) 很有趣。我从来不知道 ascii 是这样设计的!
    • 这将认为[{ 相同,* 与换行符相同,以及许多其他此类错误。此外,在处理宽字符串时假设英语几乎肯定是错误的。
    【解决方案6】:
    #include <algorithm>
    #include <string>
    #include <cstdio>
    
    
     bool icase_wchar_cmp(wchar_t a, wchar_t b)
    {
      return std::toupper(a) == std::toupper(b);
    }
    
    
    bool icase_cmp(std::wstring const& s1, std::wstring const& s2)
    {
      return (s1.size() == s2.size()) &&
                 std::equal(s1.begin(), s1.end(), s2.begin(),
                                  icase_wchar_cmp);
    }
    
    
    
    int main(int argc, char** argv)
    {
      using namespace std;
    
      wstring str1(L"Hello"), str2(L"hello");
    
      wprintf(L"%S and %S are %S\n", str1.c_str(), str2.c_str(),
                  icase_cmp(str1,str2) ? L"equal" : L"not equal");
    
      return 0;
    }
    

    【讨论】:

      【解决方案7】:

      您可以使用 mismatch() 或 lexicographical_compare()。这是 Scott Meyers 在 Effecitve STL, item 35 中提出的建议。

      【讨论】:

      • 我们这些没有那本书的人的例子会很好。
      • 请注意,默认情况下,这些函数都不会不区分大小写。您仍然需要编写一个不区分大小写比较字符并将其传递给这些函数的函数。
      【解决方案8】:

      您可以使用 boost 字符串算法库。只要你不打算做正则表达式,它就是一个只有标题的库。所以你可以很容易地做到这一点。

      http://www.boost.org/doc/libs/1_39_0/doc/html/string_algo.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-29
        • 2014-10-30
        • 2013-10-03
        • 1970-01-01
        • 2019-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多