【问题标题】:Case insensitive string comparison C++ [duplicate]不区分大小写的字符串比较C ++ [重复]
【发布时间】:2012-02-29 06:34:19
【问题描述】:

我知道有一些方法可以进行大小写忽略比较,其中涉及遍历字符串或一个 good one 上的 SO 需要另一个库。我需要把它放在其他可能没有安装它的计算机上。有没有办法使用标准库来做到这一点?现在我只是在做......

if (foo == "Bar" || foo == "bar")
{
cout << "foo is bar" << endl;
}

else if (foo == "Stack Overflow" || foo == "stack Overflow" || foo == "Stack overflow" || foo == "etc.")
{
cout << "I am too lazy to do the whole thing..." << endl;
}

这可以极大地提高我的代码的可读性和可用性。感谢您阅读本文。

【问题讨论】:

  • 认真的吗?即使没有内置方法,您也可以轻松编写一个函数来执行此操作,而不是强制每个单独的比较。遍历字符串有什么问题?无论如何,这就是您要使用的任何库要做的事情。
  • 可用的标准库取决于您计划使用哪个版本的 C++ 编译器来编译二进制文件。例如,C++0x 支持正则表达式。对于较旧的编译器,您可以使用 stricmp。
  • 您希望如何比较两个字符串而不对其进行迭代?链接问题的答案没有一个对您有帮助吗?
  • @CoffeeRain: strncasecmp 确实遍历它们。
  • @arx stricmp() 无处不在:它是微软主义(现在拼写为 _stricmp())。 strcasecmp() 也不是,它是一个 POSIX 扩展。令人难以置信的是,在 C 中仍然没有标准的方法来进行不区分大小写的字符串比较,但是你已经有了。 (至于 C++,显然你要么使用 char_traits 滚动你自己的不区分大小写的字符串,要么使用 boost。)

标签: c++ case-insensitive string-comparison


【解决方案1】:

strncasecmp

strcasecmp() 函数对字符串 s1s2 执行逐字节比较,忽略字符的大小写。如果发现 s1 分别小于、匹配或大于 s2,则它返回一个小于、等于或大于零的整数。

strncasecmp()函数类似,只是它比较的s1s2不超过n个字节... p>

【讨论】:

  • @CoffeeRain:不客气!我很高兴你喜欢一个简单的老式 C 函数而不是 mambo-jumbo C++ macaroni :)
  • 它应该是空白的吗?
  • 它是标准的 C 函数,还是仅限 POSIX?
  • @VioletGiraffe 不是标准 C,但我想你已经知道了。
【解决方案2】:

通常我所做的只是比较相关字符串的小写版本,例如:

if (foo.make_this_lowercase_somehow() == "stack overflow") {
  // be happy
}

我相信 boost 有内置的小写转换,所以:

#include <boost/algorithm/string.hpp>    

if (boost::algorithm::to_lower(str) == "stack overflow") {
  //happy time
}

【讨论】:

  • Boost 是我链接的那个...我没有那个。
  • boost 在任何意义上都是免费的,如果由于某种原因无法安装它,您可以直接从那里获取 to_lower 算法。
  • to_lower 的返回值为 void。您必须先申请to_lower,然后照常进行比较。在 gcc 上,上面的内容会给你一个“不应该被忽略的空值”错误。
  • 既然你在使用 boost,为什么不使用boost::iequals
【解决方案3】:

你为什么不把所有东西都变成小写然后比较呢?

tolower()

  int counter = 0;
  char str[]="HeLlO wOrLd.\n";
  char c;
  while (str[counter]) {
    c = str[counter];
    str[counter] = tolower(c);
    counter++;
  }

  printf("%s\n", str);

【讨论】:

  • 我尝试过,但效果不是很好。你能举个例子吗?我会尝试发布我的错误代码...
  • 请不要在超出它们需要可见的范围内声明变量。变量'c'完全在'while'循环的主体中使用,因此无需声明它在循环之外。同样,如果这是一个“for”循环,那么变量“counter”也可以在 for 循环的第一个子句中声明。用不需要的变量污染外部范围是不好的:这会导致错误和变量的意外重用。此外,在声明时立即初始化变量比让它未初始化要好得多。
【解决方案4】:

您可以编写一个简单的函数将现有字符串转换为小写,如下所示:

#include <string>
#include <ctype.h>
#include <algorithm>
#include <iterator>
#include <iostream>

std::string make_lowercase( const std::string& in )
{
  std::string out;

  std::transform( in.begin(), in.end(), std::back_inserter( out ), ::tolower );
  return out;
}

int main()
{
  if( make_lowercase( "Hello, World!" ) == std::string( "hello, world!" ) ) {
    std::cout << "match found" << std::endl;
  }

  return 0;
}

【讨论】:

    【解决方案5】:

    我刚刚写了这个,也许它对某人有用:

    int charDiff(char c1, char c2)
    {
        if ( tolower(c1) < tolower(c2) ) return -1;
        if ( tolower(c1) == tolower(c2) ) return 0;
        return 1;
    }
    
    int stringCompare(const string& str1, const string& str2)
    {
        int diff = 0;
        int size = std::min(str1.size(), str2.size());
        for (size_t idx = 0; idx < size && diff == 0; ++idx)
        {
            diff += charDiff(str1[idx], str2[idx]);
        }
        if ( diff != 0 ) return diff;
    
        if ( str2.length() == str1.length() ) return 0;
        if ( str2.length() > str1.length() ) return 1;
        return -1;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-06-20
      • 1970-01-01
      • 2013-07-22
      • 2014-07-19
      • 2011-06-22
      • 2021-05-09
      • 1970-01-01
      相关资源
      最近更新 更多