我想知道有人可以帮我实现这个方法,而我不需要使用std :: string。
该方法接受tewo参数,一个用于char数组,另一个是char数组的大小。
传递的参数将是一个由逗号分隔的不同值的数组,例如: “规则1,规则2,规则3,Rule4,AT,T,猫,狗”。
成员变量“m_rulesSet”是一个std :: string,它包含了相似的值。我想比较两者以检查“name”是否在std :: string“m_ruleSet”中
bool
Matche(const char *str, size_t strSize)
{
std::string target(str, strSize);
if(m_ruleSet.empty())
{
return true;
}
if((NULL == str) || (strSize <= 0))
{
return false;
}
const char * ptr =0;
const char * start = target.c_str();
while ((ptr = strchr(start, ',')) != 0)
{
std::string name(start, ptr - start);
if(name ==m_ruleSet)
{
return true;
}
start = ptr + 1;
}
if(*start)
{
std::string name(start);
if(name==m_ruleSet)
{
return true;
}
}
return false;
}
请提供任何帮助,非常感谢您提前
答案 0 :(得分:2)
看起来您只是使用std::string
来保存子字符串然后进行比较。制作副本以进行子字符串比较效率低下。
而不是
std::string name(start, ptr - start);
if(name ==m_ruleSet)
你可以写
if (ptr - start == m_ruleSet.size() && 0 == strncmp(start, m_ruleSet.c_str(), ptr-start))
您还应该使用memchr
并传入str
和strSize
,而不是将target
作为std::string
。
我的总体建议是使用适当的词法分析器/语法识别器,如flex + bison。这将比单独调用strchr
和strncmp
更快地生成优化的DFA。如果您要匹配多个字符串(规则),这将特别有用。
但这是一个简单的DFA:
bool csv_match( const char * const haystack, size_t const haystack_size, const char* const needle, size_t const needle_size )
{
const char * const haystack_end = haystack + haystack_size;
int state = 0;
// invariant: state == -1 if the current field doesn't match
// otherwise the first (state) characters have been matched
for( const char* p = haystack; p < haystack_end; ++p ) {
if (*p == ',') {
if (state == needle_size) return true;
state = 0;
}
else if (state < 0)
;
else if (state >= needle_size || *p != needle[state])
state = -1;
else
++state;
}
return (state == needle_size);
}
像
一样使用它bool Matche(const char *str, size_t strSize) const { return csv_match(std, strSize, m_ruleSet.data(), m_ruleSet.size()); }
答案 1 :(得分:1)
因此,您只是意味着将std::string
替换为strcmp
或strncmp
(因为这是您使用std::string
的唯一内容,其他所有内容都已使用C-字符串)?好吧,如果你真的想要它:
bool Matche(const char *str, size_t strSize)
{
if(m_ruleSet.empty())
return true;
if(!str || !strSize) //remember that size_t is unsigned by standard
return false;
const char * ptr, start = str;
while (ptr = memchr(start, ',', strSize))
{
size_t len = ptr - start;
if(len == m_ruleSet.size() && !strncmp(start, m_ruleSet.c_str(), len))
return true;
strSize -= len + 1;
start = ptr + 1;
}
return *start ? (strSize == m_ruleSet.size() &&
!strncmp(start, m_ruleSet.c_str(), strSize)) : false;
}
Ben在他的评论和回答中指出,当你得到一个额外的大小参数并且你的字符串不一定是零终止时,你需要使用memchr
而不是strchr
。
您可能还希望用C字符串替换m_ruleSet
(以摆脱.c_str()
),但我实际上质疑是否需要用C字符串替换std::string
首先是C ++代码。
答案 2 :(得分:0)
string.h/cstring提供了大多数字符串/基本内存操作方法。您应该能够找到其中几乎所有std::string
方法的替换项。如果找不到直接映射,可以使用cstring
中的方法自行编写。查看您发布的代码,肯定需要strcpy
,strncpy
(或memcpy
)。
如果您有具体问题,请将其添加到帖子中,然后有人会帮助您。
答案 3 :(得分:0)
所以你在std :: string中使用的方法是
std::string target(str, strSize);
=&gt; char * target = strdup(str)
或strcpy
m_ruleSet.empty()
=&gt; strlen(m_ruleSet.c_str())==0
name==m_ruleSet
=&gt; strcmp(name.c_str(),m_ruleSet.c_str()) == 0
答案 4 :(得分:0)
你的意思是重写
std::string name(start);
if(name==m_ruleSet)
{
return true;
}
return false;
到
return m_ruleSet == start;
?
不需要构造std::string
只是为了将它与C字符串进行比较。无论如何,std::string
的==运算符都会正常工作。
如果您需要将m_ruleSet
与另一个std::string
的子字符串或C字符串进行比较,那么std::string::compare
的几个重载就是这样做的。