【问题标题】:sequence of delimiters in function strtok函数 strtok 中的分隔符序列
【发布时间】:2011-11-16 14:38:18
【问题描述】:

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

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

谢谢!

【问题讨论】:

  • 您的意思是要传入一个分隔符数组,并在其中任何一个上标记strtok
  • 实际上,不,您的意思似乎相反。是否希望 strtok[,] 视为单个分隔符?
  • 不要在 C++ 中使用 C 字符串和 strtok,因为它有太多的陷阱并且具有破坏性。使用stringfind
  • 如果你想要 strtok 的可重入版本,可以使用 strtok_r。

标签: c++ delimiter strtok


【解决方案1】:

如果您希望strtok[,] 视为单个 令牌,则无法这样做。 strtok 始终将您在分隔符字符串中传递的任何内容视为单独的 1 字符分隔符。

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

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

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

【讨论】:

  • 天啊,我想这正是我想要的。我现在就试试。谢谢!!!!!!
【解决方案2】:

如果这真的是 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;
}

【讨论】:

    【解决方案3】:

    如果您可以使用新的 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 的《专业 C++》一书。

    【讨论】:

      【解决方案4】:

      如果你可以使用 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'
      

      【讨论】:

      • 将任何字符 [,] 视为分隔符,而不是序列 [,]
      • 无论如何我都不能使用外部库:(
      • @Urien - 羞耻 - 提升很有用 - 它只是一个头文件:-)
      • @Mike 我知道 - 但它没有创建空令牌,这是我认为 OP 想要的 - 我还没有看过但有 boost::XXXX_separator<:string>("], [")) 在提升中?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多