C++ Primer ex 5.18

Discussion in 'C++' started by arnuld, Jul 25, 2007.

  1. arnuld

    arnuld Guest

    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>::eek: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
     
    arnuld, Jul 25, 2007
    #1
    1. Advertising

  2. On Jul 25, 9:34 am, arnuld <> 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;
    >
    > }
    >
     
    tragomaskhalos, Jul 25, 2007
    #2
    1. Advertising

  3. arnuld

    James Kanze Guest

    On Jul 25, 10:34 am, arnuld <> 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:
    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
     
    James Kanze, Jul 25, 2007
    #3
  4. arnuld

    tom Guest

    On Jul 25, 4:34 pm, arnuld <> 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>::eek: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;

    }
     
    tom, Jul 25, 2007
    #4
  5. arnuld

    Jerry Coffin Guest

    In article <>,
    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.
     
    Jerry Coffin, Jul 25, 2007
    #5
  6. arnuld

    BobR Guest

    arnuld <> 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 <>
    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 <> 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
     
    BobR, Jul 25, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Richard

    SSL / authentication primer

    Richard, Jul 25, 2003, in forum: Java
    Replies:
    2
    Views:
    483
    Richard
    Jul 25, 2003
  2. Chris
    Replies:
    0
    Views:
    367
    Chris
    Apr 18, 2005
  3. Captain Dondo

    SVG primer

    Captain Dondo, Jan 21, 2006, in forum: HTML
    Replies:
    1
    Views:
    576
    Toby Inkster
    Jan 22, 2006
  4. Charles L

    'C++ Primer 2nd Ed' errata

    Charles L, Apr 11, 2004, in forum: C++
    Replies:
    2
    Views:
    365
  5. hugo
    Replies:
    1
    Views:
    360
    Ali Cehreli
    Aug 17, 2004
Loading...

Share This Page