cout formatting + copy algorithm

S

suresh

Hi
I display a vector using copy algorithm like this.

copy(v.begin(),v.end(),ostream_iterator<int>(cout," ");

suppose i want to set the width or the fill character, what can i do?
Of course I can use a for loop instead of copy algorithm but my
question is, while using copy algorithm, is it possible to format
output?

thanks
suresh
 
V

Victor Bazarov

Hi
I display a vector using copy algorithm like this.

copy(v.begin(),v.end(),ostream_iterator<int>(cout," ");

Missing a closing parenthesis before the semicolon.
suppose i want to set the width or the fill character, what can i do?
Of course I can use a for loop instead of copy algorithm but my
question is, while using copy algorithm, is it possible to format
output?

The width and fill character don't stick. You need a custom stream
object, I suppose, that on every output operation will set the width and
the fill character.

V
 
G

Gil

Hi
I display a vector using copy algorithm like this.

copy(v.begin(),v.end(),ostream_iterator<int>(cout," ");

suppose i want to set the width or the fill character, what can i do?
Of course I can use a for loop instead of copy algorithm but my
question is, while using copy algorithm, is it possible to format
output?

thanks
suresh

I believe fill character set by basic_ios::fill() should stick with
stream;
only width value set with ios_base::width doesn't 'stick' to stream
except next insertion/extraction because implementations are calling
stream.width(0) after certain I/O operations.
so you need to set width value somehow every time std::copy increments
the proxy output iterator.
you can do this every time locally with a lambda function or just
write a custom stream functor like V suggested:

/*
* ostream_it_custom_manip.cpp
*
* Created on: Sep 24, 2010
* Author: Gil
*/
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <iterator>
#include <string>
#include <vector>
#include <algorithm>
#include <boost/function_output_iterator.hpp>

template< class streamable >
struct custom_stream {
std::eek:stream & s_;
std::string sep_;
std::streamsize width_;
custom_stream( std::eek:stream & s, std::string const & sep,
int width = 0, char fill = ' ' )
: s_( s ), sep_( sep ), width_( width ) {
s_ << std::setfill( fill );
}
void operator ()( streamable const & a ) const {
s_ << std::setw( width_ ) << a << sep_;
}
};//custom_stream

int main( ) {
std::vector< int > v;
std::generate_n( std::back_inserter( v ), 10, std::rand );
std::copy( v.begin( ),
v.end( ),
boost::make_function_output_iterator(
custom_stream< int >( std::cout, "\n", 10, 'x' )
)
);
std::cout << std::endl;

return 0;
}
 
S

suresh

I believe fill character set by basic_ios::fill() should stick with
stream;
only width value set with ios_base::width doesn't 'stick' to stream
except next insertion/extraction because implementations are calling
stream.width(0) after certain I/O operations.
so you need to set width value somehow every time std::copy increments
the proxy output iterator.
you can do this every time locally with a lambda function or just
write a custom stream functor like V suggested:

/*
 * ostream_it_custom_manip.cpp
 *
 *  Created on: Sep 24, 2010
 *      Author: Gil
 */
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <iterator>
#include <string>
#include <vector>
#include <algorithm>
#include <boost/function_output_iterator.hpp>

template< class streamable >
  struct custom_stream {
    std::eek:stream & s_;
    std::string sep_;
    std::streamsize width_;
    custom_stream( std::eek:stream & s, std::string const & sep,
                   int width = 0, char fill = ' ' )
      : s_( s ), sep_( sep ), width_( width ) {
      s_ << std::setfill( fill );
    }
    void operator ()( streamable const & a ) const {
      s_ << std::setw( width_ ) << a << sep_;
    }
  };//custom_stream

int main( ) {
  std::vector< int > v;
  std::generate_n( std::back_inserter( v ), 10, std::rand );
  std::copy( v.begin( ),
             v.end( ),
             boost::make_function_output_iterator(
               custom_stream< int >( std::cout, "\n", 10, 'x' )
             )
  );
  std::cout << std::endl;

  return 0;



}

thanks for the lambda function suggestion, I wrote something like this
and managed:
for_each(v.begin(),v.end(),(cout << setw(3)<< _1 << " "));
suresh
 
J

James Kanze

On 9/24/2010 3:45 PM, suresh wrote:
Missing a closing parenthesis before the semicolon.
The width and fill character don't stick. You need a custom stream
object, I suppose, that on every output operation will set the width and
the fill character.

Fill character does, but the width doesn't. For things like
this, I tend to use std::transform, with a formatting tranformer
object.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top