如何在通过引用传递的 std::vector 上使用 std::search?
How to use std::search on a std::vector passed by reference?
如果我在 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
很大,所以复制它是可行的,但这是一个糟糕的解决方案。
为什么不能编译?
适用于 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;
}
编辑: 下面是错误的。问题是问题中的代码实际上并没有显示问题。 TartanLlama 有正确的解决方案。
Edit2: 唉: 写这篇文章的时候我心情不好。 次 char
和 unsigned char
之间的差异会导致问题 - 它们是不同的类型。然而,对 "char defaults to signed on Windows" 的引用具有误导性;它 是 true char
是否签名是实现定义的(并且在 Windows 上它默认为签名),但无论它是签名还是未签名, 它仍然是不同于 unsigned char
或 signed char
.
的类型
您的问题是 std::string::begin
returns 一个指向 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());
问题是您正在迭代 const std::vector<unsigned char>
,但您尝试将迭代器从它分配给非常量 std::vector<unsigned char>::iterator
。
一个简单的解决方法是为 itr
声明正确的类型:
std::vector<unsigned char>::const_iterator itr;
如果您使用的是 C++11,我会改用 auto
:
auto itr = std::search(vect.begin(),vect.end(),signature.begin(),signature.end());
如果我在 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
很大,所以复制它是可行的,但这是一个糟糕的解决方案。
为什么不能编译?
适用于 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;
}
编辑: 下面是错误的。问题是问题中的代码实际上并没有显示问题。 TartanLlama 有正确的解决方案。
Edit2: 唉: 写这篇文章的时候我心情不好。 次 char
和 unsigned char
之间的差异会导致问题 - 它们是不同的类型。然而,对 "char defaults to signed on Windows" 的引用具有误导性;它 是 true char
是否签名是实现定义的(并且在 Windows 上它默认为签名),但无论它是签名还是未签名, 它仍然是不同于 unsigned char
或 signed char
.
您的问题是 std::string::begin
returns 一个指向 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());
问题是您正在迭代 const std::vector<unsigned char>
,但您尝试将迭代器从它分配给非常量 std::vector<unsigned char>::iterator
。
一个简单的解决方法是为 itr
声明正确的类型:
std::vector<unsigned char>::const_iterator itr;
如果您使用的是 C++11,我会改用 auto
:
auto itr = std::search(vect.begin(),vect.end(),signature.begin(),signature.end());