iterator防止最后一项使用定界符

iterator防止最后一项使用定界符

本文介绍了std :: ostream_iterator防止最后一项使用定界符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以使用std :: ostream_iterator(或类似的方法)来使分隔符不放置在最后一个元素上?

Is there a way to use a std::ostream_iterator (or similar) such that the delimiter isn't placed for the last element?

#include <iterator>
#include <vector>
#include <algorithm>
#include <string>


using namespace std;
int main(int argc, char *argv[]) {
    std::vector<int> ints = {10,20,30,40,50,60,70,80,90};
    std::copy(ints.begin(),ints.end(),std::ostream_iterator<int>(std::cout, ","));
}

会打印

I正在尝试避免在定界符尾随。我要打印

I'm trying to avoid the trailing the delimiter. I want to print

当然,您可以使用循环:

Sure, you could use a loop:

for(auto it = ints.begin(); it != ints.end(); it++){
  std::cout << *it;
  if((it + 1) != ints.end()){
    std::cout << ",";
  }
}

但是基于C ++ 11范围的循环,这是

But given C++11 range based loops this is cumbersome to track position.

int count = ints.size();
for(const auto& i : ints){
  std::cout << i;
  if(--count != 0){
    std::cout << ",";
  }
}

我愿意使用Boost。我调查了,但需要将整数复制为字符串,所以它是两行的。

I'm open to using Boost. I looked into boost::algorithm::join() but needed to make a copy of the ints to strings so it was a two-liner.

std::vector<std::string> strs;
boost::copy(ints | boost::adaptors::transformed([](const int&i){return boost::lexical_cast<std::string>(i);}),std::back_inserter(strs));
std::cout << boost::algorithm::join(strs,",");

理想情况下,我只想使用std :: algorithm而不在最后一个定界符

Ideally I'd just like to use a std::algorithm and not have the delimiter on the last item in the range.

谢谢!

推荐答案

@Cubbi指出完全是所做的评论

@Cubbi pointed out in a comment that is is exactly what infix_iterator does

// infix_iterator.h
//
// Lifted from Jerry Coffin's 's prefix_ostream_iterator
#if !defined(INFIX_ITERATOR_H_)
#define  INFIX_ITERATOR_H_
#include <ostream>
#include <iterator>
template <class T,
          class charT=char,
          class traits=std::char_traits<charT> >
class infix_ostream_iterator :
    public std::iterator<std::output_iterator_tag,void,void,void,void>
{
    std::basic_ostream<charT,traits> *os;
    charT const* delimiter;
    bool first_elem;
public:
    typedef charT char_type;
    typedef traits traits_type;
    typedef std::basic_ostream<charT,traits> ostream_type;
    infix_ostream_iterator(ostream_type& s)
        : os(&s),delimiter(0), first_elem(true)
    {}
    infix_ostream_iterator(ostream_type& s, charT const *d)
        : os(&s),delimiter(d), first_elem(true)
    {}
    infix_ostream_iterator<T,charT,traits>& operator=(T const &item)
    {
        // Here's the only real change from ostream_iterator:
        // Normally, the '*os << item;' would come before the 'if'.
        if (!first_elem && delimiter != 0)
            *os << delimiter;
        *os << item;
        first_elem = false;
        return *this;
    }
    infix_ostream_iterator<T,charT,traits> &operator*() {
        return *this;
    }
    infix_ostream_iterator<T,charT,traits> &operator++() {
        return *this;
    }
    infix_ostream_iterator<T,charT,traits> &operator++(int) {
        return *this;
    }
};
#endif

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

using namespace std;
int main(int argc, char *argv[]) {
    std::vector<int> ints = {10,20,30,40,50,60,70,80,90};
    std::copy(ints.begin(),ints.end(),infix_ostream_iterator<int>(std::cout,","));
}

打印:

这篇关于std :: ostream_iterator防止最后一项使用定界符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 08:45