【问题标题】:boost::ifind_first with std::string objectsboost::ifind_first 与 std::string 对象
【发布时间】:2010-11-18 08:39:55
【问题描述】:

我正在尝试使用提升字符串算法进行不区分大小写的搜索。
这里是新手。

如果我以这种方式使用它,我会收到错误。

std::string str1("Hello world");
std::string str2("hello");
if ( boost::ifind_first(str1, str2) ) some code;

转换为 char 指针可以解决问题。

boost::ifind_first( (char*)str1.c_str(), (char*)str2.c_str() );

有没有办法直接搜索 std::string 对象?

另外,也许还有另一种方法可以通过不区分大小写的搜索来知道字符串是否存在于另一个字符串中?

【问题讨论】:

    标签: c++ algorithm string boost


    【解决方案1】:

    这样的事情会在不修改任何一个字符串的情况下对字符串进行不区分大小写的比较。

    int nocase_cmp(const string & s1, const string& s2) 
    {
      string::const_iterator it1=s1.begin();
      string::const_iterator it2=s2.begin();
    
      //stop when either string's end has been reached
      while ( (it1!=s1.end()) && (it2!=s2.end()) ) 
      { 
        if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
         // return -1 to indicate smaller than, 1 otherwise
         return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1; 
        //proceed to the next character in each string
        ++it1;
        ++it2;
      }
      size_t size1=s1.size(), size2=s2.size();// cache lengths
      //return -1,0 or 1 according to strings' lengths
      if (size1==size2)  {
        return 0;
      }
      return (size1<size2) ? -1 : 1;
    }
    

    【讨论】:

      【解决方案2】:

      (char*)str.c_str()实际上是在执行const_cast:const_cast&lt;char*&gt;(str.c_str())。我非常怀疑是否有必要抛弃const 才能搜索字符串。

      我从来没有用过boost::ifind_first,但是根据documentation,这个函数需要两个范围。我想有一种方法可以从字符串创建范围? OTOH,我想知道字符串是否不是完美的范围。

      如果您发布您使用的编译器的完整错误消息,这可能会有所帮助。

      【讨论】:

        【解决方案3】:

        你需要使用 boost::iterator_range。这有效:

          typedef const boost::iterator_range<std::string::const_iterator> StringRange;
          std::string str1("Hello world");
          std::string str2("hello");
        
          if ( boost::ifind_first(
                  StringRange(str1.begin(), str1.end()),
                  StringRange(str2.begin(), str2.end()) ) )
              std::cout << "Found!" << std::endl;
        

        编辑:在 typedef 中使用 const iterator_range 允许传递一个临时范围。

        【讨论】:

        • ifind_first() 的第一个参数是 Range1T&。通过临时范围是不标准的。
        • @DanielLaügt:Range1T 将被推导出为const boost::iterator_range&lt;std::string::const_iterator&gt;,从而产生一个常量引用。将 const 引用传递给临时对象时遇到问题?
        • 我没有看到 iterator_range 之前的 const。这工作正常。我不知道我们可以做这种把戏。我学到了一些东西。谢谢。
        • 但是这不能在带有 /Za 选项的 msvc 上编译。可能是微软编译器中的一个错误,因为它在 gcc 和 clang 上编译得很好......
        • 我收到一个错误 C2440: 'static_cast' : cannot convert from 'std::_String_const_iterator<_elem>' to 'std::_String_iterator<_elem>' with this VS2010中的代码。
        猜你喜欢
        • 2017-01-08
        • 2011-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-22
        • 2011-04-23
        • 1970-01-01
        • 2015-09-18
        相关资源
        最近更新 更多