使用 strtok 查找子字符串

Using strtok to find substring

本文关键字:字符串 查找 strtok 使用      更新时间:2023-10-16

我有很多字母的字符串

string path = "cxzaserds";

和目标词

string word = "cars";

在我的函数 match() 中,如果在 path 中找到 word 中的字符(按顺序),我想返回 true,在这种情况下它将返回 true("c"在"a"之前,在"r"出现在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 返回非空?还是另一个(更简单的)解决方案?

正如 Vlad 提到的,你不应该混合使用 STL 代码 ( std::string ) 和经典 c 代码 ( strtok() )。

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

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
}

你写过:

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

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

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

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

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

然后像这样使用它:

p = strtok(cstr, delimiters);

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

我已经回答了这个问题,所以我不想在这里完全重复。这个问题在这里问过,但我找不到。但是您可以在我的个人论坛上看到答案

虽然答案是用俄语写的,但代码是用英语写的:)此外,您可以使用网络服务翻译来翻译描述。

至于对std::string类型的对象使用标准 C 函数strtok,那简直是一个坏主意,不应使用。

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

strchr

strtok这个问题要好得多;实际上,正如其他人提到的strtok设计得非常糟糕,很难想象在什么情况下使用它是个好主意。

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

即使在 C 语言中,使用 strchr 的问题也变成了单行代码:

int match(const char *needle, const char *haystack) {
    while (haystack && *needle) {
        haystack = strchr(haystack, *needle++);
    }
    return haystack != NULL;
}

鉴于您的问题以及 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;
}