65.9K
CodeProject 正在变化。 阅读更多。
Home

字符串分词器迭代器类

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (6投票s)

2002年6月27日

公共领域
viewsIcon

118295

一个与 std::string 一起使用的字符串分词器迭代器类。

引言

作为更大项目的一部分,我需要编写一些基本的字符串实用函数和类。 其中一件事情是需要一种灵活的方式来将字符串拆分为单独的标记。

正如编程中经常发生的那样,解决这个问题有不同的方法。 在回顾我的选项后,我决定基于迭代器的解决方案足以满足我的需求。

针对这个特定问题的非迭代器解决方案通常具有将用户绑定到特定容器类型的缺点。 使用基于迭代器的分词器,程序员可以自由选择任何类型的容器(或者根本不使用容器)。 许多 STL 容器,例如 std::liststd::vector,都提供可以从一组迭代器填充容器的构造函数。 此功能使使用分词器变得非常容易。

Example usage

    
std::vector<std::string> s(string_token_iterator("one two three"),
                             string_token_iterator());
std::copy(s.begin(),
          s.end(),
          std::ostream_iterator<std::string>(std::cout,"\n"));
// output:
// one
// two
// three

std::copy(string_token_iterator("one,two..,..three",",."),
          string_token_iterator(),
          std::ostream_iterator<std::string>(std::cout,"\n"));
// same output as above

该代码已使用 Visual C++.NET 和 GCC 3 进行测试。

代码

#include <string>
#include <iterator>

struct string_token_iterator 
  : public std::iterator<std::input_iterator_tag, std::string>
{
public:
  string_token_iterator() : str(0), start(0), end(0) {}
  string_token_iterator(const std::string & str_, const char * separator_ = " ") :
    separator(separator_),
    str(&str_),
    end(0)
  {
    find_next();
  }
  string_token_iterator(const string_token_iterator & rhs) :
    separator(rhs.separator),
    str(rhs.str),
    start(rhs.start),
    end(rhs.end)
  {
  }

  string_token_iterator & operator++()
  {
    find_next();
    return *this;
  }

  string_token_iterator operator++(int)
  {
    string_token_iterator temp(*this);
    ++(*this);
    return temp;
  }

  std::string operator*() const
  {
    return std::string(*str, start, end - start);
  }

  bool operator==(const string_token_iterator & rhs) const
  {
    return (rhs.str == str && rhs.start == start && rhs.end == end);
  }

  bool operator!=(const string_token_iterator & rhs) const
  {
    return !(rhs == *this);
  }

private:

  void find_next(void)
  {
    start = str->find_first_not_of(separator, end);
    if(start == std::string::npos)
    {
      start = end = 0;
      str = 0;
      return;
    }

    end = str->find_first_of(separator, start);
  }

  const char * separator;
  const std::string * str;
  std::string::size_type start;
  std::string::size_type end;
};
© . All rights reserved.