Connecting Tech Pros Worldwide Forums | Help | Site Map

ostream_iterator annoyance

Wiseguy
Guest
 
Posts: n/a
#1: Jul 23 '05
consider the following:

ostream_iterator<int> i(cout,"");
cout << setw(3);
copy(int_list.begin(),int_list.end(),i);

the problem is that the field width restriction is only active for the first
element of int_list. after the first element is copied to cout the stream
setw(3) no longer has any affect.

why? and how to use stream_iterators that don't modify the state of setw()?


ostream iterators are of no use to me unless they can be used to
enforce more complicated text formatting than the
ostream_iterator(ostream&,string) constructor provides for.


--
--
dual 2.8Ghz Xeon; 2GB RAM; 500GB ATA-133; nVidia powered
Linux 2.6.10; glibc-2.3.5; vendor neutral home-brewed installation


----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Julián Albo
Guest
 
Posts: n/a
#2: Jul 23 '05

re: ostream_iterator annoyance


Wiseguy wrote:
[color=blue]
> ostream iterators are of no use to me unless they can be used to
> enforce more complicated text formatting than the
> ostream_iterator(ostream&,string) constructor provides for.[/color]

You can, for example, write a function that takes an int and returns an
object of a class that has an operator << that outputs the int with the
formatting required, and use std::transform with that function.

(Untested code)

class Format {
int num;
public:
Format (n) : num (n) { }
int get () const { return num; }
};

ostream & operator << (ostream & os, const Format & f)
{
os << setw (3) << f.get ();
}

Format make_format (int n)
{
return Format (n);
}

....

ostream_iterator <Format> i (cout,"");
transform (int_list.begin (), int_list.end (), i, make_format);


--
Salu2
Chris \( Val \)
Guest
 
Posts: n/a
#3: Jul 23 '05

re: ostream_iterator annoyance



"Wiseguy" <noone@uber.usachoice.net> wrote in message
news:42955871$1_2@spool9-west.superfeed.net...
| consider the following:
|
| ostream_iterator<int> i(cout,"");
| cout << setw(3);
| copy(int_list.begin(),int_list.end(),i);
|
| the problem is that the field width restriction is only active for the first
| element of int_list. after the first element is copied to cout the stream
| setw(3) no longer has any affect.
|
| why? and how to use stream_iterators that don't modify the state of setw()?
|
|
| ostream iterators are of no use to me unless they can be used to
| enforce more complicated text formatting than the
| ostream_iterator(ostream&,string) constructor provides for.

If you only want a fixed width for each element, then you can
easily set the width of the string:

std::ostream_iterator<int> i( std::cout, " " );

Better yet, you might obtain it dynamically:

std::string Width( 4, ' ' );
std::ostream_iterator<int> i( std::cout, Width.c_str() );

Even better yet, what about using a function object ?:

# include <iostream>
# include <iomanip>
# include <ostream>
# include <list>
# include <algorithm>

inline void SpecialFormat( int n )
{
switch( n )
{
case 1 :
case 2 :
case 5 : std::cout << std::setw( 1 ) << n;
break;
case 10 : std::cout << std::setw( 5 ) << n;
break;
case 20 : std::cout << std::setw( 10 ) << n
<< std::setw( 3 )
<< std::setfill( '.' );
break;
case 30 : std::cout << std::setw( 15 ) << n;
break;
default:
std::cout << std::setw( 2 ) << std::left << n;
break;
}
}

int main()
{
std::list<int> int_list;
int_list.push_back( 10 );
int_list.push_back( 20 );
int_list.push_back( 30 );

std::for_each( int_list.begin(), int_list.end(), SpecialFormat );

return 0;
}

There are other possibilities too.

Hope this help's.

Cheers,
Chris Val


Wiseguy
Guest
 
Posts: n/a
#4: Jul 23 '05

re: ostream_iterator annoyance


"Chris \( Val \)" <chrisval@bigpond.com.au> scribbled on the stall wall:[color=blue]
>
> "Wiseguy" <noone@uber.usachoice.net> wrote in message
> news:42955871$1_2@spool9-west.superfeed.net...[color=green]
>>[/color]
> If you only want a fixed width for each element, then you can
> easily set the width of the string:
>
> std::ostream_iterator<int> i( std::cout, " " );[/color]
[color=blue]
> Better yet, you might obtain it dynamically:
>
> std::string Width( 4, ' ' );
> std::ostream_iterator<int> i( std::cout, Width.c_str() );
>[/color]

how does that enforce a field width?...the above would just ALWAYS put
n-spaces after each item sent to the stream, right? that's not what I
want because my purpose is to use the iterators in stl algorithms like
copy.

[color=blue]
> Even better yet, what about using a function object ?:[color=green]
>>[/color]
> inline void SpecialFormat( int n )
> {
> }[/color]

unfortunately the function object is not generic enough and needs to work with
stl algorithms. that's the whole purpose behind my quest: a generic ways of
using iterators that preserve the special formatting and (state) information of
the stream they are acting upon.

seems that for something like

o << setw(4) << something;

the field width restriction is only valid for the duration of the previous
statement and that adding another

o << somethign_else;

would NOT respect the previous setw()...that's the point of my contention.

so, a more related question would be "how to make something like setw()
permanent for the duration of a stream's existence?"


--
--
dual 2.8Ghz Xeon; 2GB RAM; 500GB ATA-133; nVidia powered
Linux 2.6.10; glibc-2.3.5; vendor neutral home-brewed installation


----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Pete Becker
Guest
 
Posts: n/a
#5: Jul 23 '05

re: ostream_iterator annoyance


Wiseguy wrote:
[color=blue]
>
> so, a more related question would be "how to make something like setw()
> permanent for the duration of a stream's existence?"
>[/color]

That's not _really_ what you want. That would affect all insertions, not
just the ones you're currently interested in.

The way to do it is to write your own variation of ostream_iterator that
does a setw before each insertion. It's not very complicated, just a bit
tedious.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Chris \( Val \)
Guest
 
Posts: n/a
#6: Jul 23 '05

re: ostream_iterator annoyance



"Wiseguy" <noone@uber.usachoice.net> wrote in message
news:4295e957$1_2@spool9-west.superfeed.net...
| "Chris \( Val \)" <chrisval@bigpond.com.au> scribbled on the stall wall:
| >
| > "Wiseguy" <noone@uber.usachoice.net> wrote in message
| > news:42955871$1_2@spool9-west.superfeed.net...
| >>
| > If you only want a fixed width for each element, then you can
| > easily set the width of the string:
| >
| > std::ostream_iterator<int> i( std::cout, " " );
|
| > Better yet, you might obtain it dynamically:
| >
| > std::string Width( 4, ' ' );
| > std::ostream_iterator<int> i( std::cout, Width.c_str() );
| >
|
| how does that enforce a field width?...the above would just ALWAYS put
| n-spaces after each item sent to the stream, right?

Right.

| that's not what I want because my purpose is to use the iterators
| in stl algorithms like copy.
|
| > Even better yet, what about using a function object ?:
| >>
| > inline void SpecialFormat( int n )
| > {
| > }
|
| unfortunately the function object is not generic enough and needs to work with
| stl algorithms. that's the whole purpose behind my quest: a generic ways of
| using iterators that preserve the special formatting and (state) information of
| the stream they are acting upon.
|
| seems that for something like
|
| o << setw(4) << something;
|
| the field width restriction is only valid for the duration of the previous
| statement and that adding another
|
| o << somethign_else;
|
| would NOT respect the previous setw()...that's the point of my contention.

Nor should it.

| so, a more related question would be "how to make something like setw()
| permanent for the duration of a stream's existence?"

I'm sorry, but I agree with 'Pete Becker' here.

Cheers,
Chris Val


Closed Thread