函数 strtok 中的分隔符序列

发布于 2024-12-15 14:59:56 字数 286 浏览 2 评论 0原文

我正在尝试使用 C++ 中的函数 strtok() 获取令牌。当您仅使用 1 个分隔符时,非常简单,例如: token = strtok(auxiliar,"[,]");。每次函数找到[]时,都会剪切auxiliar

我想要的是获取带有一系列分隔符的标记,例如:[,] 可以使用 strtok 函数来做到这一点吗?我找不到路。

谢谢你!

im trying to obtain tokens with function strtok() in C++. Is very simple when you use just 1 delimiter like:
token = strtok(auxiliar,"[,]");. This will cut auxiliar everytime the function finds [,,or].

What I want is obtain tokens with a sequence of delimiters like: [,]
It is posible doing that with strtok function? I cannot find the way.

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

生死何惧 2024-12-22 14:59:56

如果您希望 strtok[,] 视为单个标记,则无法完成此操作。 strtok 始终将您在分隔符字符串中传递的任何内容视为单独的 1 字符分隔符。

除此之外,无论如何最好不要在 C++ 中使用 strtok。它不是可重入的(例如,不能嵌套调用),不是类型安全的,并且非常容易以产生令人讨厌的错误的方式使用。

最简单的解决方案是简单地使用 std::string 在循环中搜索所需的特定分隔符。如果您需要更复杂的功能,Boost 库中有标记器,我还发布了仅使用标准库进行更全面标记化的代码,此处

我上面链接的代码也将分隔符视为单个字符,但我认为代码可以按照您想要的方式扩展。

If you want strtok to treat [,] as a single token, this cannot be done. strtok always treats whatever you pass in the delimiters string as individual, 1-character delimiters.

Beyond this, it's best to not use strtok in C++ anyway. It is not re-entrant (eg, you can't nest calls), not type-safe, and very easy to use in a way that creates nasty bugs.

The simplest solution is to simply search withing a std::string for the particular delimiter you want, in a loop. If you need more sophisticated functionality, there are tokenizers in the Boost library, and I've also posted code to do more comprehensive tokenizing using only the Standard Library, here.

The code I've linked above also treats delimiters as single characters, but I think the code could be extended in the way you desire.

£噩梦荏苒 2024-12-22 14:59:56

如果这确实是 C++,则应该使用 std::string 而不是 C 字符串。

下面是一个仅使用 STL 将 std::string 拆分为 std::vector 的示例:

#include <cstddef>
#include <string>
#include <vector>

std::vector<std::string> split(std::string str, std::string sep) {
    std::vector<std::string> vec;

    size_t i = 0, j = 0;
    do {
        i = str.find(sep, j);
        vec.push_back( str.substr(j, i-j) );
        j = i + sep.size();
    } while (i != str.npos);

    return vec;
}

int main() {
    std::vector<std::string> vec = split("This[,]is[[,]your, string", "[,]");
    // vec is contains "This", "is[", "your, string"

    return 0;
}

If this is really C++, you should use std::string and not C strings.

Here's an example that uses only the STL to split a std::string into a std::vector:

#include <cstddef>
#include <string>
#include <vector>

std::vector<std::string> split(std::string str, std::string sep) {
    std::vector<std::string> vec;

    size_t i = 0, j = 0;
    do {
        i = str.find(sep, j);
        vec.push_back( str.substr(j, i-j) );
        j = i + sep.size();
    } while (i != str.npos);

    return vec;
}

int main() {
    std::vector<std::string> vec = split("This[,]is[[,]your, string", "[,]");
    // vec is contains "This", "is[", "your, string"

    return 0;
}
雨轻弹 2024-12-22 14:59:56

如果您可以使用新的 C++11 功能,则可以使用正则表达式和标记迭代器来实现。例如:

regex reg("\[,\]");
const sregex_token_iterator end;
string aux(auxilar);
for(sregex_token_iterator iter(aux.begin(), aux.end(), reg); iter != end; ++iter) {
    cout << *iter << endl;
}

这个例子来自 Wrox 的《Professional C++》一书。

If you can use the new C++11 features, you can do it with regex and token iterators. For example:

regex reg("\[,\]");
const sregex_token_iterator end;
string aux(auxilar);
for(sregex_token_iterator iter(aux.begin(), aux.end(), reg); iter != end; ++iter) {
    cout << *iter << endl;
}

This example is from the Wrox book Professional C++.

半步萧音过轻尘 2024-12-22 14:59:56

如果你可以使用 boost 库,我认为这会做你想做的事 - 不完全确定,因为你的问题有点不清楚

#include <iostream>
#include <vector>
#include <string>

#include <boost/tokenizer.hpp>

int main(int argc, char *argv[])
{
   std::string data("[this],[is],[some],[weird],[fields],[data],[I],[want],[to],[split]");

   boost::tokenizer<boost::char_separator<char> > tokens(data, boost::char_separator<char>("],["));

   std::vector<std::string> words(tokens.begin(), tokens.end());

   for(std::vector<std::string>::const_iterator i=words.begin(),end=words.end(); i!=end; ++i)
   {
      std::cout << '\'' << *i << "'\n";
   }
   return 0;
}

这会产生以下输出

'this'
'is'
'some'
'weird'
'fields'
'data'
'I'
'want'
'to'
'split'

If you can use the boost library I think this will do what you want it to do - not totally sure though as your question is a little unclear

#include <iostream>
#include <vector>
#include <string>

#include <boost/tokenizer.hpp>

int main(int argc, char *argv[])
{
   std::string data("[this],[is],[some],[weird],[fields],[data],[I],[want],[to],[split]");

   boost::tokenizer<boost::char_separator<char> > tokens(data, boost::char_separator<char>("],["));

   std::vector<std::string> words(tokens.begin(), tokens.end());

   for(std::vector<std::string>::const_iterator i=words.begin(),end=words.end(); i!=end; ++i)
   {
      std::cout << '\'' << *i << "'\n";
   }
   return 0;
}

This produces the following output

'this'
'is'
'some'
'weird'
'fields'
'data'
'I'
'want'
'to'
'split'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文