Velocity Reviews - Computer Hardware Reviews

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

Reply
Thread Tools

C++ Primer ex 5.18

 
 
arnuld
Guest
Posts: n/a
 
      07-25-2007
it does not run and even does not even give me any clue to the problem in
its output

/* C++ Primer - 4/e
* chapter 5 - Expressions

* exercise 5.18
* STATEMENT
* write a programme that defines a vector of pointers to strings.
read the vector, printing each string and its corresponding size.

*/

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

int main()
{
std::vector<std::string*> psvec;
std::string input_string;
std::string* ps;

while(std::cin >> input_string)
{
*ps = input_string;
psvec.push_back(ps++);
}

/* printing the strings pointed by the pointers in the vector*/
for(std::vector<std::string*>::const_iterator iter = psvec.begin();
iter != psvec.end(); ++iter)
{
std::cout << "string: " << **iter
<< " size: " << (*iter).size() /* error is here */
<< std::endl;
/* double-defrenced operator because it points to a pointer
rather than a value */
}

/* i was thinking of using "std::copy" from <algorithm> and
"ostream_iterator" from <sstream> from but was not able to
understand the peculiar mechanism of both of them */

return 0;
}

/* OUTPUT
/home/arnuld/programming/cpp $ g++ -ansi -pedantic -Wall -Wextra

ex_05-18.cpp ex_05-18.cpp: In function ‘int main()’: ex_05-18.cpp:32:
error: request for member ‘size’ in ‘iter.

__gnu_cxx::__normal_iterator<_Iterator, _Container>:perator* [with
_Iterator = std::string* const*, _Container = std::vector<std::string*,
std::allocator<std::string*> >]()’, which is of non-class type
‘std::string* const’

/home/arnuld/programming/cpp $

*/

--
-- http://arnuld.blogspot.com

 
Reply With Quote
 
 
 
 
tragomaskhalos
Guest
Posts: n/a
 
      07-25-2007
On Jul 25, 9:34 am, arnuld <(E-Mail Removed)> wrote:
> it does not run and even does not even give me any clue to the problem in
> its output


See code markups (without benefit of compiler, but I hope correct !)

>
> int main()
> {
> std::vector<std::string*> psvec;
> std::string input_string;

// WARNING: ps is uninitialised here ...
> std::string* ps;
>
> while(std::cin >> input_string)
> {

// DISASTER IMMINENT: dereferencing uninitialised pointer
// You need to use dynamically created std::strings in here instead
> *ps = input_string;
> psvec.push_back(ps++);
> }
>
> /* printing the strings pointed by the pointers in the vector*/
> for(std::vector<std::string*>::const_iterator iter = psvec.begin();
> iter != psvec.end(); ++iter)
> {
> std::cout << "string: " << **iter

// PROBLEM: Type of *iter is const std::string *, so you need (*iter)-
>size()
> << " size: " << (*iter).size() /* error is here */
> << std::endl;
> }
>
> return 0;
>
> }
>


 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      07-25-2007
On Jul 25, 10:34 am, arnuld <(E-Mail Removed)> wrote:
> it does not run and even does not even give me any clue to the problem in
> its output


> /* C++ Primer - 4/e
> * chapter 5 - Expressions
>
> * exercise 5.18
> * STATEMENT
> * write a programme that defines a vector of pointers to strings.
> read the vector, printing each string and its corresponding size.
> */


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


> int main()
> {
> std::vector<std::string*> psvec;
> std::string input_string;
> std::string* ps;


> while(std::cin >> input_string)
> {
> *ps = input_string;


What does ps point to here? Somehow, you're going to have to
get memory to which the pointer can point.

> psvec.push_back(ps++);
> }


> /* printing the strings pointed by the pointers in the vector*/
> for(std::vector<std::string*>::const_iterator iter = psvec.begin();
> iter != psvec.end(); ++iter)
> {
> std::cout << "string: " << **iter
> << " size: " << (*iter).size() /* error is here */


What is the type of *iter?

C++ has a moderately strict type system. Whatever *iter
returns, it should have the value type of the array. What type
does the array contain? Is the . operator legal on such types?
What operators might be legal?

> << std::endl;
> /* double-defrenced operator because it points to a pointer
> rather than a value */
> }


> /* i was thinking of using "std::copy" from <algorithm> and
> "ostream_iterator" from <sstream> from but was not able to
> understand the peculiar mechanism of both of them */


You can't use it if you want to output the size as well. (Well,
actually you can, but doing so would require some funny
business, and is probably not a good idea.)

> return 0;
> }


--
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
 
tom
Guest
Posts: n/a
 
      07-25-2007
On Jul 25, 4:34 pm, arnuld <(E-Mail Removed)> wrote:
> it does not run and even does not even give me any clue to the problem in
> its output
>
> /* C++ Primer - 4/e
> * chapter 5 - Expressions
>
> * exercise 5.18
> * STATEMENT
> * write a programme that defines a vector of pointers to strings.
> read the vector, printing each string and its corresponding size.
>
> */
>
> #include <iostream>
> #include <vector>
> #include <string>
>
> int main()
> {
> std::vector<std::string*> psvec;
> std::string input_string;
> std::string* ps;
>
> while(std::cin >> input_string)
> {
> *ps = input_string;
> psvec.push_back(ps++);
> }
>
> /* printing the strings pointed by the pointers in the vector*/
> for(std::vector<std::string*>::const_iterator iter = psvec.begin();
> iter != psvec.end(); ++iter)
> {
> std::cout << "string: " << **iter
> << " size: " << (*iter).size() /* error is here */
> << std::endl;
> /* double-defrenced operator because it points to a pointer
> rather than a value */
> }
>
> /* i was thinking of using "std::copy" from <algorithm> and
> "ostream_iterator" from <sstream> from but was not able to
> understand the peculiar mechanism of both of them */
>
> return 0;
>
> }
>
> /* OUTPUT
> /home/arnuld/programming/cpp $ g++ -ansi -pedantic -Wall -Wextra
>
> ex_05-18.cpp ex_05-18.cpp: In function 'int main()': ex_05-18.cpp:32:
> error: request for member 'size' in 'iter.
>
> __gnu_cxx::__normal_iterator<_Iterator, _Container>:perator* [with
> _Iterator = std::string* const*, _Container = std::vector<std::string*,
> std::allocator<std::string*> >]()', which is of non-class type
> 'std::string* const'
>
> /home/arnuld/programming/cpp $
>
> */
>
> --
> --http://arnuld.blogspot.com


fixed your program and post it below:

int main()
{
std::vector<std::string*> psvec;
//std::string input_string;
//std::string* ps;
std::string *pstring(NULL);
pstring = new string;
// modification: fix run-time error here to allocate space to store
input string
while(std::cin >> *pstring)
{
psvec.push_back(pstring);
pstring = new string;
}
delete pstring;


/* printing the strings pointed by the pointers in the vector*/
for(std::vector<std::string*>::const_iterator iter = psvec.begin();
iter != psvec.end(); ++iter)
{
std::cout << "string: " << **iter
<< " size: " << (*iter)->size() /* error is here */ //
modification: made here to get it compilied
<< std::endl;
/* double-defrenced operator because it points to a pointer
rather than a value */
}

//modification: clean up dynamically allocated memory
while(psvec.size()>0)
{
std::vector<std::string *>::iterator iter = psvec.begin();
delete *iter;
psvec.erase(iter);
}

/* i was thinking of using "std::copy" from <algorithm> and
"ostream_iterator" from <sstream> from but was not able to
understand the peculiar mechanism of both of them */


return 0;

}

 
Reply With Quote
 
Jerry Coffin
Guest
Posts: n/a
 
      07-25-2007
In article <(E-Mail Removed)>,
http://www.velocityreviews.com/forums/(E-Mail Removed) says...

[ ... ]

> #include <iostream>
> #include <vector>
> #include <string>
>
> int main()
> {
> std::vector<std::string*> psvec;
> std::string input_string;
> std::string* ps;


As has already been pointed out, this has type 'std::string *', but it's
not really a pointer to a string -- it's just an unitialized pointer.

> while(std::cin >> input_string)
> {
> *ps = input_string;


This really needs to allocate a new string and copy the input_string
into the new string, something like:

ps = new string(input_string);

As it stands right now, it's _trying_ to take wherever the uninitialized
pointer happens to point at, and treat it as if there was a string
there. If you're lucky, it'll point to somewhere that's not readable or
writable, so your program will die immediately when you try to do that
-- but chances of being that lucky aren't very high. The alternative is
that it sort of seems to work for a while, overwriting memory that
doesn't belong to it. That inevitably leads to eventual problems, but
it's hard to predict when they'll become visible -- Murphy's law being
what it is, you'll usually find out about it by the program dying a
horrible death just as you're showing it to the person who's in the best
position to fire you...

> /* printing the strings pointed by the pointers in the vector*/
> for(std::vector<std::string*>::const_iterator iter = psvec.begin();
> iter != psvec.end(); ++iter)
> {
> std::cout << "string: " << **iter
> << " size: " << (*iter).size() /* error is here */
> << std::endl;
> /* double-defrenced operator because it points to a pointer
> rather than a value */
> }
>
> /* i was thinking of using "std::copy" from <algorithm> and
> "ostream_iterator" from <sstream> from but was not able to
> understand the peculiar mechanism of both of them */


They're going to be pretty tough to apply in a case like this -- for the
most part, the standard containers and algorithms expect to work with
value-like objects, not with pointers. By value-like objects, I mean
things that it's free to copy, assign, etc. There's an implicit
assumption that such operations are also relatively cheap.

--
Later,
Jerry.

The universe is a figment of its own imagination.
 
Reply With Quote
 
BobR
Guest
Posts: n/a
 
      07-25-2007

arnuld <(E-Mail Removed)> wrote in message...
>
> /* i was thinking of using "std::copy" from <algorithm> and


> "ostream_iterator" from <sstream> from but was not able to
> understand the peculiar mechanism of both of them */



----- Original Message -----
From: James Kanze <(E-Mail Removed)>
Newsgroups: comp.lang.c++
Sent: Tuesday, July 24, 2007 2:38 AM
Subject: Re: any improvements for this programme

On Jul 23, 6:15 pm, arnuld <(E-Mail Removed)> wrote:
> >> ...[SNIPPED]........

> yes it works. dinot know that "ostream_iterator" is defined in
> "<sstream>" header.


The <sstream> header is for the ostringstream.

ostream_iterator is defined in <iterator>.

(But any standard header is allowed to include any other,
and <iterator> is likely included in a header you've already included.)

END ----- Original Message -----


Did you forget?

--
Bob R
POVrookie


 
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