Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change delimiter's position?

Tags:

c++

iterator

This example :

#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
    int v[] = { 1, 2, 3 };

    std::copy( &v[0], &v[3], std::ostream_iterator< int >( std::cout, "\n " ) );
}

produces next output :

1
 2
 3
 

Is there a way to change the example to make it produce next output?


 1
 2
 3

PS I know I could use the for loop, but I am interested in a solution that uses algorithms and iterators.

like image 1000
BЈовић Avatar asked Jan 21 '26 01:01

BЈовић


2 Answers

There is no way to do this with std::ostream_iterator. (IMHO, there should be, but it's not there.) If you don't mind writing an extra small function or class, you can use std::transform, e.g.:

struct FormatString
{
    std::string operator()( std::string const& original ) const
    {
        return ' ' + original + '\n';
    }
};

//  ...
std::transform(
    v.begin(), v.end(),
    std::ostream_iterator<std::string>( std::cout ), 
    FormatString() );

If you have C++11, you can use a lambda for the FormatString.

I find the need for this occurs often enough that I've written a PatsubstTransformer—a functional object which basically implements the $(patsubst...) function of GNU make. So I would just have to write:

std::transform(
    v.begin(), v.end(),
    std::ostream_iterator<std::string>( std::cout ),
    PatsubstTransformer( "%", " %\n" ) );

I find I use this a lot. (I also find using std::transform more appropriate than std::copy, since what I'm outputting is a transformation.)

like image 60
James Kanze Avatar answered Jan 23 '26 17:01

James Kanze


If you want to use C++11 you can use a lambda.

e.g like this:

int v[] = { 1, 2, 3};

std::for_each( &v[0], &v[3], [](int i){ std::cout << " " << i << "\n";} );
like image 36
mkaes Avatar answered Jan 23 '26 16:01

mkaes