473,385 Members | 2,015 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

C++ Primer ex 9.14

/* 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::stringsvec;
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::ostream_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

Sep 16 '07 #1
11 1445
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::stringsvec;
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::ostream_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
Sep 16 '07 #2
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

Sep 16 '07 #3
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::stringslist;
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::ostream_iterator<std::string>( std::cout, "\n" ) );
return 0;
}
--
http://lispmachine.wordpress.com

Sep 16 '07 #4
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::ostream_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
Sep 16 '07 #5
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... 8-)

--
http://lispmachine.wordpress.com

Sep 16 '07 #6
On Sep 16, 1:02 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
[...]
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:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 16 '07 #7
James Kanze wrote:
On Sep 16, 1:02 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
[...]
>>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
Sep 17 '07 #8
On Sep 17, 3:42 am, Barry <dhb2...@gmail.comwrote:
James Kanze wrote:
On Sep 16, 1:02 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
[...]
>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:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 17 '07 #9
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
Sep 17 '07 #10
On Sep 17, 11:11 am, Barry <dhb2...@gmail.comwrote:
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?
Yes:-).

The declaration:
std::istream_iterator< std::string toto() ;
declares a function, with the name toto. As a function
parameter, the name is optional (so we end up with
"std::istream_iterator< std::string >()", AND "After determining
the type of each parameter, any parameter of type 'array of T'
or 'function returning T' is adjusted to be 'pointer to T' or
'pointer to function returning T,' respectively" (§8.3.5/3).

A horrible misfeature, inherited from C, but one we have to live
with.
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.
Certainly. It matches a template type argument. It can only be
a type. A non-type wouldn't be legal in this context.
If you say "it differs if context differs", would you tell me more?
See above. A function is a perfectly valid type. But not as a
function parameter. In a function declaration, function types
behave much like array types; they are adjusted to pointer to
function. (Note that in general, too, an expression of type
function will be implicitly converted to a pointer to function,
unless it is the operand of a () operator.)
it's the equivalent of:
std::istream_iterator< std::string >(*ptrToFnc)()
actually, they are not equivent
As a function parameter, they are exactly the same.
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.
Note that I'm not aware of a modern compiler which has this
problem. G++ had it for a long time, however, and I've gotten
into the habit of programming against it. (Also, I prefer
orthogonality.)
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
);
Introducing an additional named variable? That makes sense when
the name adds some significant semantic information, but the two
iterator idiom is so ubiquious that this isn't the case here.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 18 '07 #11
you guys are talking of alien life on Mars :P

(actually, I was only able to understand a little more than 1/3rd of
it)

Sep 18 '07 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Sandman | last post by:
Could anyone give me a tip about a good primer on object oriented php programming - why I should use it, the benefits, the drawbacks, the bugs, the glory? And, should I upgrade to php5 before...
1
by: Charles L | last post by:
Does anyone know where I can find errata for Stan Lippman's 'C++ Primer 2nd Edition'? Charles Leng
1
by: hugo | last post by:
what is L&L ,people or book?
5
by: hajime | last post by:
I purchased this book: C++ Primer, 4th Edition ISBN: 0201721481 in Australia. The right side of the last three lines on page 231 are not legible. A stain shows a piece of paper was on that part...
7
by: Lycan. Mao.. | last post by:
Hello, I am a newbie in C++ and I'm in trouble in choosing books, I hope some one who can give me some tips. I'm already know C and a little about Scheme, C#, Python, Lua and so on, and now I want...
2
by: W. Watson | last post by:
Is there a primer out there on these two items? I have the Python tutorial, but would like either a Tkinter tutorial/primer to supplement it, or a primer/tutorial that addresses both. Maybe there's...
20
by: arnuld | last post by:
I get an error, can't find what is the problem: /* C++ Primer - 4/e * * Chapter 8, exercise 8.3 * STATEMENT * write a function that takes and returns an istream&. the function should read...
2
by: xianwei | last post by:
First, typedef struct pair { Node *parent; Node *child; } Pair; static Pair SeekItem(cosnt Item *pI, const Tree *pTree) { Pair look;
1
by: Kveldulv | last post by:
Hi all, here is the code: http://pastebin.com/m6e74d36b I'm stuck at highfink constructor, last line before #endif. As parameters, I have reference to one parent class and int member of another...
0
by: cincerite | last post by:
Hello , guys , I'm reading C++ Primer 3rd edition recently.I tried to download the errata of it from Stan Lippman's Home Page:http:// staff.develop.com/slip/ ,but it says:We're Sorry, we could not...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.