使用strtok查找子字符串

时间:2015-04-16 07:05:47

标签: c++ strtok

我有一串很多字母

string path = "cxzaserds";

和目标词

string word = "cars";

在我的函数match()中,如果在路径中找到word中的字符(按顺序),我想返回true,在这种情况下它将返回true('c'在'a'之前'之前'''在path字符串中的's'之前。

我正在尝试使用strtok()一个接一个地找到每个字符,分隔符是当前索引的字母。

我的进步:

bool match (string path, string word)
{
  char * cstr = new char [path.length()+1]; //workaround for strtok on string
  std::strcpy (cstr, path.c_str());

    char *p;

  for (int i = 0 ; i < path.length(); i++)
    {
    //error here, "invalid conversion from 'char' to 'const char*'
      p = strtok (cstr, word[i]);

      if (p != NULL) //if strtok found word[i]
        continue;
      else return false; //was NULL, word not found
    }

  return true; //made it through, return true
}

在C ++页面的分隔符下,它说:

这些可能因呼叫而异。

http://www.cplusplus.com/reference/cstring/strtok/

如果更改分隔符,我可以做什么,因为strtok返回非null?或者另一个(更简单的)解决方案?

5 个答案:

答案 0 :(得分:0)

我已经回答了这个问题,所以我不想在这里完全重复。这个问题在这里被问到但我找不到。 但是,您可以在my personal forum

看到答案

尽管答案是用俄语写的,但代码是用英文写的。:)而且你可以使用网络服务翻译翻译描述。

对于使用标准C函数strtokstd::string类型的对象,那么这只是一个坏主意,不会被使用。

另一种方法是使用标准算法std::all_of以及标准C函数strchr

答案 1 :(得分:0)

您已写过:

p = strtok(cstr, word[i]);

作为第二个参数,您传递i个字符(类型为char)。

但是,正如文档所述,第二个参数必须是const char *类型,这意味着它是一个分隔符数组。所以你的类型不匹配。

最简单的解决方案是创建一个分隔符数组(注意它NUL - 终止,它实际上是一个只有一个字母的C风格字符串):

char delimiters[] = { word[i], '\0' };

然后像这样使用它:

p = strtok(cstr, delimiters);

另一方面,这种方法是非C ++风格,可能在现实生活中你想要别的东西。

答案 2 :(得分:0)

对于这个问题,

strchrstrtok要好得多;实际上正如其他人提到的那样strtok设计得非常糟糕,并且很难想出使用它的好主意。

strchr查找C字符串中第一次出现的字符。

即使在C:

中,使用strchr的问题也会成为一个问题
int match(const char *needle, const char *haystack) {
    while (haystack && *needle) {
        haystack = strchr(haystack, *needle++);
    }
    return haystack != NULL;
}

答案 3 :(得分:0)

正如弗拉德所说,你不应该混合使用STL代码(std::string)和经典c代码(strtok())。

相反,您可以使用std::string成员(例如find()find_first_of()来解决您的问题:

bool match(const std::string &path, const std::string &word) {
    std::size_t pos = 0; // position of the last match

    // iterate over all characters in 'word'
    for (std::size_t i = 0; i < word.length(); ++i) {
        // look for the next character and store the new position
        if ((pos = path.find(word[i], pos)) == std::string::npos)
            return false; // return false if it couldn't be found
    }
    return true; // all characters have been found in order
}

答案 4 :(得分:0)

鉴于您的问题以及C / C ++允许您使用普通下标来处理单个字符的事实,那么strtok似乎只会使解决方案复杂化。

像(未经测试的代码!):

boolean hasWord ( char * needle, char * haystack) {
   int nlen = strlen(needle);
   int npos = 0;
   int hlen = strlen(haystack);
   int hpos = 0;
   for (hpos = 0 ; hpos < hlen ; hpos++) {
        if (needle[npos] == haystack[hpos]) {
            // got a match now look for next letter
            npos++;
            if (npos >= nlen) {
                // all letters now matched in sequence
                return true;
            }
        }
   }
   return false;
}