用const char *替换std :: string

时间:2012-02-27 18:55:17

标签: c++

我想知道有人可以帮我实现这个方法,而我不需要使用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;
}

请提供任何帮助,非常感谢您提前

5 个答案:

答案 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并传入strstrSize,而不是将target作为std::string

我的总体建议是使用适当的词法分析器/语法识别器,如flex + bison。这将比单独调用strchrstrncmp更快地生成优化的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替换为strcmpstrncmp(因为这是您使用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中的方法自行编写。查看您发布的代码,肯定需要strcpystrncpy(或memcpy)。

如果您有具体问题,请将其添加到帖子中,然后有人会帮助您。

答案 3 :(得分:0)

所以你在std :: string中使用的方法是

  • Char * ctor

std::string target(str, strSize); =&gt; char * target = strdup(str)或strcpy

  • .empty()

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的几个重载就是这样做的。