Borland字符串::查找bug
Borland string::find bug
我支持使用Borland c++ Builder 5.02(从1997年开始)编写的c++应用程序。Borland字符串类上的find()方法的行为不符合我的预期:
#include <cstring>
#include <iostream>
int main (int argc, char *argv[])
{
string needle = "length == eighteen";
string haystack = "<" + needle + ">";
if (haystack.find(needle) != NPOS)
cout << "Found it!" << endl;
else
cout << "Not found" << endl;
return 0;
}
程序输出Not found
。如果我把针换成短点的,它输出Found it!
。如果我把尖括号换成其他字符,它会找到它。空格可以用,但括号也不行。
请注意,我在这里使用Borland字符串库:如果我#include <string>
并使用std::string
,那么它的工作方式正是我所期望的。遗憾的是,将整个应用程序更改为使用STL字符串并不是一个可行的答案!
从文档中可以看出,Borland使用基于散列的算法进行字符串搜索。我找不到关于这个的更多细节,我已经完成了拆卸,但没有多少智慧。
我发现很难相信这真的是字符串库中的一个bug,特别是因为如果是的话,我希望能够找到一篇关于它的文章或其他东西。我找不到这样的资料。
然而,我已经没有主意了!这是已知的bug吗?有解决办法吗?
编辑:再次看了拆解,我认为它试图做一些像Rabin-Karp算法,其中哈希函数计算mod 33554393(最大的素数<2 ^ 25)。它很可能是一个以32为底的多项式哈希函数(即a_0 + 32 a_1 + 32^2 a_2 +…)+ 32^n a_n)不过这只是直觉。听起来像是Daniel Fischer建议的可能溢出我发现了一个1998年的参考,建议Borland的搜索字符串的实现有一个错误:
https://groups.google.com/forum/?fromgroups= ! searchin bug/borland.public.cpp.language/装运箱20美元/borland.public.cpp.language/XBzjaJmCYpk/gtMPm-j8jugJ
而且,似乎在历史上的某个时刻,c++委员会决定将字符串类作为标准c++的一部分,而cstring的string类是这一点的残余:
https://groups.google.com/forum/?fromgroups= ! searchin/borland.public.cpp.language/宝蓝装运箱20美元/borland.public.cpp.language/2 psy2serms4/ywVrqwU1C2wJ
如果您使用的是原始的bc++ 5.02安装盘,则字符串类source在BC5 source RTL source string下。
下面是string::find_case_index()函数(由string::find()调用)的代码摘录:
const long q = 33554393L;
const long q32 = q<<5;
size_t testlength = length() - startindex;
size_t patternlength = patl = strlen(cp);
if( testlength < patternlength )
return NPOS;
if( patternlength == 0 )
return 0;
long patternHash = 0;
long testHash = 0;
const char _FAR *testP = c_str()+startindex;
const char _FAR *patP = cp;
long x = 1;
size_t i = patternlength-1;
while( i-- )
x = (x<<5)%q;
for( i=0; i<patternlength; i++ )
{
patternHash = ( (patternHash<<5) + *patP++ ) % q;
testHash = ( (testHash <<5) + *testP++ ) % q;
}
testP = c_str()+startindex;
const char _FAR *end = testP + testlength - patternlength;
while (1)
{
if(testHash == patternHash)
if( !get_paranoid_check_flag() ||
!strncmp( testP, cp, patternlength) )
return (size_t)(testP-c_str());
if( testP >= end )
break;
// Advance & calculate the new hash value:
testHash = ( testHash + q32 - *testP * x ) % q;
testHash = ( (testHash<<5) + *(patternlength + testP++) ) % q;
}
return NPOS; // Not found.
您没有使用Borland字符串库。String
(大写S)是Borland字符串类。string
(小写s),与std::string
完全相同,是STL字符串类,这不是Borland实现(BCB5中的STL是RogueWave STL)。使用#include <cstring>
可能会将std::string
带入全局名称空间,这就是代码编译的原因。但你真的应该使用#include <string>
和std::string
代替。至于NPOS
,您应该使用string::npos
代替,因为这是string::find()
实际返回的。
#include <cstring>
#include <iostream>
int main (int argc, char *argv[])
{
string needle = "length == eighteen";
string haystack = "<" + needle + ">";
if (haystack.find(needle) != string::npos)
cout << "Found it!" << endl;
else
cout << "Not found" << endl;
return 0;
}
或:
#include <string>
#include <iostream>
int main (int argc, char *argv[])
{
std::string needle = "length == eighteen";
std::string haystack = "<" + needle + ">";
if (haystack.find(needle) != std::string::npos)
std::cout << "Found it!" << std::endl;
else
std::cout << "Not found" << std::endl;
return 0;
}
- 正在查找文档以获得PS4平台的C++中的设备信息
- 在C++中查找文件
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 查找最接近的大于当前数字的数字的索引
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 查找后更改类变量
- 使用正则表达式regex_search在字符串中查找字符串
- 使用gcc从静态链接的文件中查找可选符号
- Clang bug?使用指针作为模板参数
- 在C++中查找范围的长度
- 算法问题:查找从堆栈中弹出的所有序列
- 在Windows中查找扬声器输出的当前音量级别
- 如何在C++中使用X509证书模在令牌中查找私钥
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 在 for 循环中查找问题时遇到困难
- 如何在文件中查找字节序列
- Borland字符串::查找bug
- c++查找与链表相关的代码bug