C++ std::ostream_迭代器阻止最后一项使用分隔符
有没有一种方法可以使用std::ostream_迭代器(或类似的迭代器),这样就不会为最后一个元素放置分隔符C++ std::ostream_迭代器阻止最后一项使用分隔符,c++,iostream,stl-algorithm,C++,Iostream,Stl Algorithm,有没有一种方法可以使用std::ostream_迭代器(或类似的迭代器),这样就不会为最后一个元素放置分隔符 #include <iterator> #include <vector> #include <algorithm> #include <string> using namespace std; int main(int argc, char *argv[]) { std::vector<int> ints = {1
#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, ","));
}
#包括
#包括
#包含但需要将int复制到字符串,所以它是一个两行程序
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::向量strs;
boost::copy(ints | boost::adapters::transformed([](const int&i){return boost::lexical_cast(i);}),std::back_inserter(strs));
std::cout复制可以实现为:
template<class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
while (first!=last) {
*result = *first;
++result; ++first;
}
return result;
}
因此,分隔符将附加到输出迭代器的每个赋值上。为避免将分隔符追加到最后一个向量元素,应将最后一个元素分配给不带分隔符的输出迭代器,例如:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
std::vector<int> ints = {10,20,30,40,50,60,70,80,90};
std::copy(ints.begin(), ints.end()-1, std::ostream_iterator<int>(std::cout, ","));
std::copy(ints.end()-1, ints.end(), std::ostream_iterator<int>(std::cout));
std::cout << std::endl;
return 0;
}
@库比在评论中指出,这正是他所做的
//中缀迭代器.h
//
//摘自Jerry Coffin的前缀“ostream”迭代器
#如果!已定义(中缀迭代器)
#定义中缀迭代器
#包括
#包括
模板
类中缀\u ostream\u迭代器:
公共标准:迭代器
{
标准::基本的_ostream*操作系统;
图表常量*分隔符;
布尔第一要素;
公众:
类型定义图表字符类型;
typedef-traits-traits_-type;
typedef std::基本类型类型;
中缀ostream迭代器(ostream类型&s)
:操作系统(&s),分隔符(0),第一个元素(true)
{}
中缀ostream迭代器(ostream类型&s,图表常量*d)
:操作系统(&s),分隔符(d),第一个元素(true)
{}
中缀迭代器和运算符=(T常量和项)
{
//以下是ostream_迭代器的唯一真正变化:
//通常,'*os这会更容易。不知道这是你想要的
#include<iostream>
#include<algorithm>
#include<vector>
#include<iterator>
int main()
{
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,","));
std::cout<<(char)8;
}
#包括
#包括
#包括
#包括
int main()
{
std::vector ints={10,20,30,40,50,60,70,80,90};
std::copy(ints.begin()、ints.end()、std::ostream_迭代器(std::cout,“,”);
std::cout使用std::string的擦除方法:
string join (const vector< vector<int> > data, const char* separator){
vector< vector<int> > result(data[0].size(), vector<int>(data.size()));
stringstream rowStream;
vector<string> rowVector;
for (size_t i = 0; i < data.size(); i++ ){
copy(data[i].begin(), data[i].begin() + data[i].size(), ostream_iterator<int>(rowStream, " "));
rowVector.push_back(rowStream.str().erase(rowStream.str().length()-1));
rowStream.str("");
rowStream.clear();
}
copy(rowVector.begin(), rowVector.begin() + rowVector.size(), ostream_iterator<string>(rowStream, separator));
return rowStream.str().erase(rowStream.str().length()-3);
}
字符串联接(常量向量数据,常量字符*分隔符){
向量结果(数据[0].size(),向量(数据.size());
溪流-溪流;
向量行向量;
对于(size_t i=0;i
是否回答此问题?在std::copy行中迭代到倒数第二个值,而不是::end,然后打印最后一项。@Cubbi[infix\u迭代器][确实有效。很好,它是代码中std::ostream_迭代器的替代品。再想一想,第二次调用copy
真的没有意义。我不能说它更简单,但我不喜欢在流中插入后台空间是一个两行程序。当多次调用它时,它就变成了error pro氖。
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
std::vector<int> ints = {10,20,30,40,50,60,70,80,90};
std::copy(ints.begin(), ints.end()-1, std::ostream_iterator<int>(std::cout, ","));
std::copy(ints.end()-1, ints.end(), std::ostream_iterator<int>(std::cout));
std::cout << std::endl;
return 0;
}
10,20,30,40,50,60,70,80,90
// 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,","));
}
#include<iostream>
#include<algorithm>
#include<vector>
#include<iterator>
int main()
{
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,","));
std::cout<<(char)8;
}
string join (const vector< vector<int> > data, const char* separator){
vector< vector<int> > result(data[0].size(), vector<int>(data.size()));
stringstream rowStream;
vector<string> rowVector;
for (size_t i = 0; i < data.size(); i++ ){
copy(data[i].begin(), data[i].begin() + data[i].size(), ostream_iterator<int>(rowStream, " "));
rowVector.push_back(rowStream.str().erase(rowStream.str().length()-1));
rowStream.str("");
rowStream.clear();
}
copy(rowVector.begin(), rowVector.begin() + rowVector.size(), ostream_iterator<string>(rowStream, separator));
return rowStream.str().erase(rowStream.str().length()-3);
}