字节流中的字符串搜索

问题描述

我有下面的程序,我试图在 const unsigned char * byte 中搜索子字符串

list<polygon_with_holes_2> res;
S.polygons_with_holes (back_inserter (res));
list<polygon_with_holes_2>::iterator i = res.begin();
polygon_with_holes_2 mink = *i;
minkOuter = mink.outer_boundary();
cout << minkOuter << endl;
int numHoles = mink.holes_end()-mink.holes_begin();
cout << numHoles << endl;

但这可能会导致高性能系统中的核心转储并且查找功能也很昂贵。

在 const unsigned char* 缓冲区中搜索字符串的最佳方法是什么? 假设不支持高级 C++ 功能

使用旧版本的 c++(03) 和高级版本的 c++(11) 解决这个问题的最佳方法是什么?

解决方法

该操作可能会导致核心转储,因为它具有未定义的行为 - std::string 期望一个指向以空字符结尾的字符数组的指针,而您传递给它的数组不是以空字符结尾的。因此,std::string 构造函数读取缓冲区边界外的内存,直到找到空终止符为止——此操作可以轻松地进行 SEGFAULT。

您需要拥有的一件事是缓冲区的长度。然后就可以把它传递给字符串的构造函数了:

const std::string charStr{ reinterpret_cast<const char*>(byte),bufferLength };

现在,如果由于某种原因此操作对性能至关重要,您很可能不想分配缓冲区并将整个字符串复制到其中。 为避免这种情况,您可以使用 string_view,c++17 中的 std::string_view 或 abseil c++11 库中的 absl::string_view。您将相同的参数传递给构造函数,并且 string_view 将视图保持在字符范围内,而不复制它(注意缓冲区的生命周期!)。您可以像在 find 上一样在 string_view 上调用 std::string

如果您可以编辑缓冲区的内容和大小,那么最简单的方法似乎是在缓冲区末尾添加一个空终止符 '\0' 并从 std::strstr<cstring> /p>

,

第一种方法(简单):如果您能够修改数组并在末尾添加 \0x00 字符,则可以使用 C 函数 strstr

第二:您可以编写自己的搜索功能版本。很简单。

,

如果您在数组末尾添加 '\0' 或 0x00,您的代码应该可以正常工作。

您正在搜索子字符串,这很“昂贵”。你可以自己实现它,但它会和 find 完全一样。

遍历字节数组并仅查找第一个字母,如果找到,则比较搜索字符串的其余部分。但听起来或多或少是“发现”。