Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > C++ Primer ex 9.14

Reply
Thread Tools

C++ Primer ex 9.14

 
 
arnuld
Guest
Posts: n/a
 
      09-16-2007
/* C++ Primer - 4/e
*
* STATEMENT
* write a program to read sequence of strings from the standard
* input into a vector. Print the vector.
*
*/

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

int main()
{
std::vector<std::string> svec;
std::string word;

while( std::cin >> word )
{
svec.push_back( word );
}

/* print the vector */
std::cout << "\n\n----- You Entered -------\n\n";
std::copy( svec.begin(), svec.end(),
std:stream_iterator<std::string>( std::cout, "\n" ) );


return 0;
}


It runs fine. Is there any way I can replace what while loop with
std::copy ?

--
http://lispmachine.wordpress.com

 
Reply With Quote
 
 
 
 
=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
Guest
Posts: n/a
 
      09-16-2007
On 2007-09-16 12:43, arnuld wrote:
> /* C++ Primer - 4/e
> *
> * STATEMENT
> * write a program to read sequence of strings from the standard
> * input into a vector. Print the vector.
> *
> */
>
> #include <iostream>
> #include <string>
> #include <vector>
> #include <iterator>
>
> int main()
> {
> std::vector<std::string> svec;
> std::string word;
>
> while( std::cin >> word )
> {
> svec.push_back( word );
> }
>
> /* print the vector */
> std::cout << "\n\n----- You Entered -------\n\n";
> std::copy( svec.begin(), svec.end(),
> std:stream_iterator<std::string>( std::cout, "\n" ) );
>
>
> return 0;
> }
>
>
> It runs fine. Is there any way I can replace what while loop with
> std::copy ?


Might be, you would have to use std::istream_iterators and a back insert
iterator to add the elements to the vector, something like (untested):

std::copy(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>() // The same as end() for a stream
std::back_insert_iterator<std::vector>(vec)
);

--
Erik Wikström
 
Reply With Quote
 
 
 
 
arnuld
Guest
Posts: n/a
 
      09-16-2007
> On Sun, 16 Sep 2007 11:02:15 +0000, Erik Wikström wrote:
> Might be, you would have to use std::istream_iterators and a back insert
> iterator to add the elements to the vector, something like (untested):
>
> std::copy(
> std::istream_iterator<std::string>(std::cin),
> std::istream_iterator<std::string>() // The same as end() for a stream
> std::back_insert_iterator<std::vector>(vec)
> );



it works:

std::copy( std::istream_iterator<std::string>( std::cin ),
std::istream_iterator<std::string>(),
std::back_insert_iterator<std::vector<std::string> >( svec ) );

~/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra ex_09-14.cpp
~/programming/c++ $ ./a.out
Erik Wikstrom Helps arnuld


----- You Entered -------

Erik
Wikstrom
Helps
arnuld
~/programming/c++ $




--
http://lispmachine.wordpress.com

 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      09-16-2007
> On Sun, 16 Sep 2007 16:38:22 +0500, arnuld wrote:

> ~/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra ex_09-14.cpp
> ~/programming/c++ $ ./a.out
> Erik Wikstrom Helps arnuld
>
>
> ----- You Entered -------
>
> Erik
> Wikstrom
> Helps
> arnuld
> ~/programming/c++ $
>
>
>


even the same programme works for std::list:

/* C++ Primer - 4/e
*
* STATEMENT
* write a program to read sequence of strings from the standard
* input into a list. Print the list.
*
*/

#include <iostream>
#include <string>
#include <list>
#include <iterator>

int main()
{
std::list<std::string> slist;
std::string word;

/*
while( std::cin >> word )
{
svec.push_back( word );
}
*/

std::copy( std::istream_iterator<std::string>( std::cin ),
std::istream_iterator<std::string>(),
std::back_insert_iterator<std::list<std::string> >( slist ) );


/* print the vector */
std::cout << "\n\n----- You Entered -------\n\n";
std::copy( slist.begin(), slist.end(),
std:stream_iterator<std::string>( std::cout, "\n" ) );


return 0;
}


--
http://lispmachine.wordpress.com

 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      09-16-2007
Erik Wikström wrote:
> On 2007-09-16 12:43, arnuld wrote:
>> /* C++ Primer -
>> 4/e
>> *
>> *
>> STATEMENT
>> * write a program to read sequence of strings from the
>> standard *
>> input into a vector. Print the
>> vector.
>> *
>> */
>>
>> #include
>> <iostream>
>> #include
>> <string>
>> #include
>> <vector>
>> #include
>> <iterator>
>>
>> int
>> main()
>> {
>> std::vector<std::string>
>> svec;
>> std::string
>> word;
>>
>> while( std::cin >> word
>> )
>>
>> {
>> svec.push_back( word
>> );
>>
>> }
>>
>> /* print the vector
>> */
>> std::cout << "\n\n----- You Entered
>> -------\n\n";
>> std::copy( svec.begin(),
>> svec.end(),
>> std:stream_iterator<std::string>( std::cout, "\n" )
>> );
>>
>>
>> return
>> 0;
>> }
>>
>> It runs fine. Is there any way I can replace what while loop with
>> std::copy ?

>
> Might be, you would have to use std::istream_iterators and a back insert
> iterator to add the elements to the vector, something like (untested):
>
> std::copy(
> std::istream_iterator<std::string>(std::cin),
> std::istream_iterator<std::string>() // The same as end() for a stream
> std::back_insert_iterator<std::vector>(vec)


std::back_insert_iterator<std::vector<std::string> >(vec)

or just simply use adapter, which is more straightforward

std::back_inserter(vec)

> );
>



--
Thanks
Barry
 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      09-16-2007
> On Sun, 16 Sep 2007 20:43:21 +0800, Barry wrote:

> or just simply use adapter, which is more straightforward
>
> std::back_inserter(vec)


cool...

--
http://lispmachine.wordpress.com

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      09-16-2007
On Sep 16, 1:02 pm, Erik Wikstrm <(E-Mail Removed)> wrote:
[...]
> > It runs fine. Is there any way I can replace what while loop with
> > std::copy ?


> Might be, you would have to use std::istream_iterators and a back insert
> iterator to add the elements to the vector, something like (untested):


> std::copy(
> std::istream_iterator<std::string>(std::cin),
> std::istream_iterator<std::string>() // The same as end() for a stream
> std::back_insert_iterator<std::vector>(vec)
> );


Even simpler would be to use the istream_iterators to initialize
the container. Something like:

std::vector< std::string > vec(
(std::istream_iterator< std::string >( std::cin )),
(std::istream_iterator< std::string >()) ) ;

(Note that the outermost parentheses around the arguments are
necessary to prevent the compiler from interpreting the
statement as a function declaration.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      09-17-2007
James Kanze wrote:
> On Sep 16, 1:02 pm, Erik Wikstrm <(E-Mail Removed)> wrote:
> [...]
>>> It runs fine. Is there any way I can replace what while loop with
>>> std::copy ?

>
>> Might be, you would have to use std::istream_iterators and a back insert
>> iterator to add the elements to the vector, something like (untested):

>
>> std::copy(
>> std::istream_iterator<std::string>(std::cin),
>> std::istream_iterator<std::string>() // The same as end() for a stream
>> std::back_insert_iterator<std::vector>(vec)
>> );

>
> Even simpler would be to use the istream_iterators to initialize
> the container. Something like:
>
> std::vector< std::string > vec(
> (std::istream_iterator< std::string >( std::cin )),

^ ^
if it's not for formatting, then it's
not necessary as std::cin is not a type,


> (std::istream_iterator< std::string >()) ) ;
>
> (Note that the outermost parentheses around the arguments are
> necessary to prevent the compiler from interpreting the
> statement as a function declaration.)


and it's not a function declaration I think. As "TypeA ()" is a function
type who returns "TypeA". So if the compiler wrongly interpret this way,
then it will report that "passing a type is illegal" (I just made this
wording )

>


it only happens to those with none parameter like the latter one you wrote.

--
Thanks
Barry
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      09-17-2007
On Sep 17, 3:42 am, Barry <(E-Mail Removed)> wrote:
> James Kanze wrote:
> > On Sep 16, 1:02 pm, Erik Wikstrm <(E-Mail Removed)> wrote:
> > [...]
> >>> It runs fine. Is there any way I can replace what while loop with
> >>> std::copy ?


> >> Might be, you would have to use std::istream_iterators and a back insert
> >> iterator to add the elements to the vector, something like (untested):


> >> std::copy(
> >> std::istream_iterator<std::string>(std::cin),
> >> std::istream_iterator<std::string>() // The same as end() for a stream
> >> std::back_insert_iterator<std::vector>(vec)
> >> );


> > Even simpler would be to use the istream_iterators to initialize
> > the container. Something like:


> > std::vector< std::string > vec(
> > (std::istream_iterator< std::string >( std::cin )),


> ^ ^
> if it's not for formatting, then it's
> not necessary as std::cin is not a type,


I'm not sure. You may be right, because I don't think that
std::cin is a legal variable name in this context. But the more
frequent:
(std::istream_iterator< std::string >( input )),
does require them.

> > (std::istream_iterator< std::string >()) ) ;


> > (Note that the outermost parentheses around the arguments are
> > necessary to prevent the compiler from interpreting the
> > statement as a function declaration.)


> and it's not a function declaration I think. As "TypeA ()" is
> a function type who returns "TypeA". So if the compiler
> wrongly interpret this way, then it will report that "passing
> a type is illegal" (I just made this wording )


> it only happens to those with none parameter like the latter
> one you wrote.


std::istream_iterator< std::string >()

would be a declaration---in the context of a function parameter,
it's the equivalent of:
std::istream_iterator< std::string >(*ptrToFnc)()
And while I think you're right for
std::istream_iterator< std::string >( std::cin ),
something like:
std::istream_iterator< std::string >( someFile ),
is definitely a declaration.

Technically, too, it should be sufficient to disambiguate any
one of the parameters; adding the parentheses to just one of the
parameters should suffice. But I've had problems with this in
the past, and have gotten into the habit of adding them more or
less systematically, whenever there might be an ambiguity.

(This is really something that needs fixing, although I don't
have a good solution. Imagine the poor beginner, who originally
writes the code without the extra parentheses, using std::cin,
and it works fine. He then replaces std::cin with a file, and
suddenly gets compiler errors when he tries to use vec, further
down in his code.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      09-17-2007
James Kanze wrote:


>> it only happens to those with none parameter like the latter
>> one you wrote.

>
> std::istream_iterator< std::string >()
>
> would be a declaration---in the context of a function parameter,


declaration of what?
a function or a pointer to function?

I think this needs more discussion:

see:

template <class F = void()>
struct Func;

template <class RET, class ARG>
struct Func <RET(ARG)>
{
};

Func<int(int)> int_int_f;

here "int(int)" is a type I think, not a variable.

If you say "it differs if context differs", would you tell me more?


> it's the equivalent of:
> std::istream_iterator< std::string >(*ptrToFnc)()


actually, they are not equivent

int (f)(int); : f is typeof function
int (*pf) (int); : pf is typeof pointer to function.

> And while I think you're right for
> std::istream_iterator< std::string >( std::cin ),
> something like:
> std::istream_iterator< std::string >( someFile ),
> is definitely a declaration.
>
> Technically, too, it should be sufficient to disambiguate any
> one of the parameters; adding the parentheses to just one of the
> parameters should suffice. But I've had problems with this in
> the past, and have gotten into the habit of adding them more or
> less systematically, whenever there might be an ambiguity.


yeh, it depends on the compiler, I think, though I don't use many compilers.

maybe adding "()" around the variable is still not the ultimate
solution, it *may* (I don't have any test case) still fail to compile on
some compilers.

the most portable way, but not so elegant would be

std::istream_iterator< std::string > end;

vector<...> vec(
...
end
);


>
> (This is really something that needs fixing, although I don't
> have a good solution. Imagine the poor beginner, who originally
> writes the code without the extra parentheses, using std::cin,
> and it works fine. He then replaces std::cin with a file, and
> suddenly gets compiler errors when he tries to use vec, further
> down in his code.)
>


, considerate

--
Thanks
Barry
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
SVG primer Captain Dondo HTML 1 01-22-2006 02:08 PM
HTPC Primer, Part I - Video and Audio Silverstrand Front Page News 0 10-21-2005 01:28 PM
PC TV Tuner Primer Silverstrand Front Page News 0 10-19-2005 01:47 PM
Primer needed: Java & Windows Security Chris Java 0 04-18-2005 09:08 PM
SSL / authentication primer Richard Java 2 07-25-2003 02:08 PM



Advertisments