【问题标题】:How to use std::search on a std::vector passed by reference? [closed]如何在通过引用传递的 std::vector 上使用 std::search? [关闭]
【发布时间】:2017-02-18 17:31:25
【问题描述】:

如果我在 C++ 中有一个通过引用获取 std::vector<unsigned char> 的函数,我如何使用 std::search 来查找签名?

代码如下所示:

int check (const std::vector<unsigned char>& vect)
{
  std::string signature("<!-- signature -->");
  std::string signature2("<!-- another -->");
  std::vector<unsigned char>::iterator itr;
  unsigned int kind = 0;

  itr = std::search(vect.begin(),vect.end(),signature.begin(),signature.end());
  if (itr!=vect.end()) kind=1;
  if (kind == 0) 
  {
    itr = std::search(vect.begin(),vect.end(),signature2.begin(),signature2.end());
    if (itr!=vect.end()) kind=2;
  }
  return kind;
}

vect 很大,所以复制它是可行的,但不是一个好的解决方案。

为什么这不能编译?

【问题讨论】:

  • 编译器告诉你什么...?

标签: c++ algorithm search iterator pass-by-reference


【解决方案1】:

编辑:以下错误。问题是问题中的代码实际上并没有显示问题。 TartanLlama 有正确的解决方案。

Edit2:叹息:我写这篇文章的时候心情不好。 charunsigned char 之间的差异会导致问题 - 它们是不同的类型。然而,对“char 默认在 Windows 上签名”的引用具有误导性; char 是否已签名是实现定义的(在 Windows 上默认为已签名),但无论它是签名还是未签名,它仍然是不同于两者的类型unsigned charsigned char

您的问题是std::string::begin 将迭代器返回给 char,而您的向量包含 unsigned char。我怀疑您在 Windows 上,其中 char 默认为已签名。

解决方法是重新解释演员表(在这种情况下是安全的):

const auto sigstart = reinterpret_cast<const unsigned char*>(&signature.front());
const auto itr = std::search(vect.begin(), vect.end(),
                             sigstart, sigstart+signature.len());

【讨论】:

  • 这根本不是问题,charunsigned char可以和==比较就好了。
  • @Angew:是的。明白了:-(。
  • 不是堆积如山,但这似乎是一个常见的误解。 charsigned charunsigned char三种不同的类型;普通char 的有符号或无符号选择是特定于实现的,但不会改变char 是一个不同类型的事实,即它既不是signed char 也不是unsigned char
  • @PeteBecker:说得好。
【解决方案2】:

问题是您正在迭代 const std::vector&lt;unsigned char&gt;,但您尝试将迭代器分配给非 const std::vector&lt;unsigned char&gt;::iterator

一个简单的解决方法是为itr 声明正确的类型:

std::vector<unsigned char>::const_iterator itr;

如果您使用的是 C++11,我只会使用 auto

auto itr = std::search(vect.begin(),vect.end(),signature.begin(),signature.end());

【讨论】:

    【解决方案3】:

    适用于 gcc-5.1,example here:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    bool check (const std::vector<unsigned char>& vect)
    {
      std::string signature("<!-- signature -->");
      auto itr = std::search(vect.begin(),vect.end(),signature.begin(),signature.end());
      if (itr!=vect.end()) /* do something */
        return false;
    }
    
    int main() {
        check(std::vector<unsigned char>{'a', 'b', 'c'});
        return 0;
    }
    

    【讨论】:

    • 对不起。我在制作示例时更正了我的代码。我使用了 std::vector::iterator itr;
    • 您的代码有效,但我的代码比示例复杂得多。
    • @R.F.Luis 那么您希望我们解决我们无法在您未向我们展示的代码中重现的问题吗?祝你好运......
    • 对不起,对不起。几十kB的代码我发不出来,只好举个例子。
    • @R.F.Luis 这当然是正确的做法,但示例必须忠实地再现实际错误!
    猜你喜欢
    • 2019-05-10
    • 2012-10-26
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 2020-12-24
    • 2013-09-05
    相关资源
    最近更新 更多