如何标记 C 中的字符串?

新手上路,请多包涵

Java有一个方便的拆分方法:

 String str = "The quick brown fox";
String[] results = str.split(" ");

有没有一种简单的方法可以在 C++ 中做到这一点?

原文由 Bill the Lizard 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 759
2 个回答

C++ 标准库算法非常普遍地基于迭代器而不是具体容器。不幸的是,这使得很难在 C++ 标准库中提供类似 Java 的 split 函数,尽管没有人认为这会很方便。但它的返回类型是什么? std::vector<std::basic_string<…>> ?也许吧,但随后我们被迫执行(可能是冗余且成本高昂的)分配。

相反,C++ 提供了多种基于任意复杂分隔符来拆分字符串的方法,但它们都没有像其他语言那样被封装得那么好。无数种方式 填满了整个博客文章

在最简单的情况下,您可以使用 std::string::find 进行迭代,直到您点击 std::string::npos ,然后使用 std::string::substr 提取内容。

在空格上拆分的更流畅(和惯用但基本)的版本将使用 std::istringstream

 auto iss = std::istringstream{"The quick brown fox"};
auto str = std::string{};

while (iss >> str) {
    process(str);
}

使用 std::istream_iterator s ,字符串流的内容也可以使用其迭代器范围构造函数复制到向量中。

多个库(例如 Boost.Tokenizer )提供特定的标记器。

更高级的拆分需要正则表达式。 C++为此特别提供了 std::regex_token_iterator

 auto const str = "The quick brown fox"s;
auto const re = std::regex{R"(\s+)"};
auto const vec = std::vector<std::string>(
    std::sregex_token_iterator{begin(str), end(str), re, -1},
    std::sregex_token_iterator{}
);

原文由 Konrad Rudolph 发布,翻译遵循 CC BY-SA 4.0 许可协议

我写了一个 https://stackoverflow.com/a/50247503/3976739 的简化版本(可能有点效率)供我自己使用。我希望它会有所帮助。

 void StrTokenizer(string& source, const char* delimiter, vector<string>& Tokens)
{
   size_t new_index = 0;
   size_t old_index = 0;

   while (new_index != std::string::npos)
   {
      new_index = source.find(delimiter, old_index);
      Tokens.emplace_back(source.substr(old_index, new_index-old_index));

      if (new_index != std::string::npos)
          old_index = ++new_index;
   }
}

原文由 Tanzer 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题