"ispunct()" not working on std::string

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

  1. arnuld

    arnuld Guest

    /* C++ Primer 4/e
    * section 3.2 - String Standard Library

    * exercise 3.10
    * STATEMENT
    * write a programme to strip the punctation from the string. */

    #include <iostream>
    #include <string>

    int main()
    {
    std::cout << "Enter a string: ";
    std::string a_word, stripped_word;
    std::cin >> a_word;

    for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    {
    if(ispunct(a_word[ix]) == 0)
    stripped_word[ix] = a_word[ix];
    }

    std::cout << stripped_word << std::endl;

    return 0;
    }

    --
    -- http://arnuld.blogspot.com
    arnuld, Jul 18, 2007
    #1
    1. Advertising

  2. arnuld

    arnuld Guest

    On Wed, 18 Jul 2007 14:07:59 +0500, arnuld wrote:

    > /* C++ Primer 4/e
    > * section 3.2 - String Standard Library
    >
    > * exercise 3.10
    > * STATEMENT
    > * write a programme to strip the punctation from the string. */
    >
    > #include <iostream>
    > #include <string>
    >
    > int main()
    > {
    > std::cout << "Enter a string: ";
    > std::string a_word, stripped_word;
    > std::cin >> a_word;
    >
    > for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    > {
    > if(ispunct(a_word[ix]) == 0)
    > stripped_word[ix] = a_word[ix];
    > }
    >
    > std::cout << stripped_word << std::endl;
    >
    > return 0;
    > }



    SORRY, i forgot to post the output:

    [arnuld@arch cpp ]% g++ -ansi -pedantic -Wall -Wextra ex_03-10.cpp
    [arnuld@arch cpp ]% ./a.out
    Enter a string: comp.lang.c++

    [arnuld@arch cpp ]%


    you see, it does not prinit anything at all but it compiled successfully.
    where is the bug ?


    --
    -- http://arnuld.blogspot.com
    arnuld, Jul 18, 2007
    #2
    1. Advertising

  3. On Wed, 18 Jul 2007 14:07:59 +0500, arnuld wrote:

    > /* C++ Primer 4/e
    > * section 3.2 - String Standard Library
    >
    > * exercise 3.10
    > * STATEMENT
    > * write a programme to strip the punctation from the string. */
    >
    > #include <iostream>
    > #include <string>
    >
    > int main()
    > {
    > std::cout << "Enter a string: ";
    > std::string a_word, stripped_word;
    > std::cin >> a_word;
    >
    > for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    > {
    > if(ispunct(a_word[ix]) == 0)
    > stripped_word[ix] = a_word[ix];


    A std::string is not an open array, you can't just assign
    to random non-existing positions.

    stripped_word += a_word[ix];
    or
    stripped_word.append(a_word[ix]);

    > }
    >
    > std::cout << stripped_word << std::endl;
    >
    > return 0;
    > }
    >


    --
    Obnoxious User
    Obnoxious User, Jul 18, 2007
    #3
  4. arnuld

    anon Guest

    arnuld wrote:
    > /* C++ Primer 4/e
    > * section 3.2 - String Standard Library
    >
    > * exercise 3.10
    > * STATEMENT
    > * write a programme to strip the punctation from the string. */
    >
    > #include <iostream>
    > #include <string>
    >
    > int main()
    > {
    > std::cout << "Enter a string: ";
    > std::string a_word, stripped_word;
    > std::cin >> a_word;
    >
    > for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    > {
    > if(ispunct(a_word[ix]) == 0)
    > stripped_word[ix] = a_word[ix];
    > }
    >
    > std::cout << stripped_word << std::endl;
    >
    > return 0;
    > }
    >


    Here is the fixed (hack) version:


    #include <iostream>
    #include <string>

    int main()
    {
    std::cout << "Enter a string: ";
    std::string a_word, stripped_word;
    std::cin >> a_word;

    for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    {
    if(ispunct(a_word.at(ix)) == 0)
    stripped_word.append(1,a_word.at(ix));
    }

    std::cout << stripped_word << std::endl;

    return 0;
    }
    anon, Jul 18, 2007
    #4
  5. arnuld

    Ian Collins Guest

    arnuld wrote:
    > /* C++ Primer 4/e
    > * section 3.2 - String Standard Library
    >
    > * exercise 3.10
    > * STATEMENT
    > * write a programme to strip the punctation from the string. */
    >
    > #include <iostream>
    > #include <string>
    >
    > int main()
    > {
    > std::cout << "Enter a string: ";
    > std::string a_word, stripped_word;
    > std::cin >> a_word;
    >
    > for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    > {
    > if(ispunct(a_word[ix]) == 0)
    > stripped_word[ix] = a_word[ix];
    > }
    >
    > std::cout << stripped_word << std::endl;
    >
    > return 0;
    > }
    >

    As well as the other suggestions, you could use:

    for( std::string::const_iterator ix = a_word.begin();
    ix != a_word.end(); ++ix )
    {
    if(ispunct(*ix) == 0)
    stripped_word += *ix;
    }


    --
    Ian Collins.
    Ian Collins, Jul 18, 2007
    #5
  6. arnuld

    arnuld Guest

    > On Wed, 18 Jul 2007 09:26:44 +0000, Obnoxious User wrote:


    > A std::string is not an open array, you can't just assign to random
    > non-existing positions.


    ok, got it


    > stripped_word += a_word[ix];


    this works. we are just concatenating 2 string objects. right ?


    > stripped_word.append(a_word[ix]);


    [arnuld@arch cpp ]% g++ -ansi -pedantic -Wall -Wextra ex_03-10.cpp
    ex_03-10.cpp: In function ‘int main()’: ex_03-10.cpp:21: error: no
    matching function for call to ‘std::basic_string<char,
    std::char_traits<char>, std::allocator<char> >::append(char&)’
    /usr/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.tcc:330:
    note: candidates are: std::basic_string<_CharT, _Traits, _Alloc>&
    std::basic_string<_CharT, _Traits, _Alloc>::append(const
    std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits
    = std::char_traits<char>, _Alloc = std::allocator<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.tcc:347:
    note: std::basic_string<_CharT, _Traits, _Alloc>&
    std::basic_string<_CharT, _Traits, _Alloc>::append(const
    std::basic_string<_CharT, _Traits, _Alloc>&, typename
    _Alloc::rebind<_CharT>::eek:ther::size_type, typename
    _Alloc::rebind<_CharT>::eek:ther::size_type) [with _CharT = char, _Traits =
    std::char_traits<char>, _Alloc = std::allocator<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.tcc:303:
    note: std::basic_string<_CharT, _Traits, _Alloc>&
    std::basic_string<_CharT, _Traits, _Alloc>::append(const _CharT*, typename
    _Alloc::rebind<_CharT>::eek:ther::size_type) [with _CharT = char, _Traits =
    std::char_traits<char>, _Alloc = std::allocator<char>]
    /usr/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.h:824:
    note: std::basic_string<_CharT, _Traits, _Alloc>&
    std::basic_string<_CharT, _Traits, _Alloc>::append(const _CharT*) [with
    _CharT = char, _Traits = std::char_traits<char>, _Alloc =
    std::allocator<char>] <near match>
    /usr/lib/gcc/i686-pc-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.tcc:286:
    note: std::basic_string<_CharT, _Traits, _Alloc>&
    std::basic_string<_CharT, _Traits, _Alloc>::append(typename
    _Alloc::rebind<_CharT>::eek:ther::size_type, _CharT) [with _CharT = char,
    _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
    [arnuld@arch cpp ]%
    [arnuld@arch cpp ]% g++ --version
    g++ (GCC) 4.2.1 20070704 (prerelease) Copyright (C) 2007 Free Software
    Foundation, Inc. This is free software; see the source for copying
    conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.

    [arnuld@arch cpp ]%


    --
    -- http://arnuld.blogspot.com
    arnuld, Jul 18, 2007
    #6
  7. arnuld wrote:
    > [..]
    > can you tell me how this works or just point me to someplave which
    > explains that:
    >
    > stripped_word.append(1,a_word.at(ix));
    >
    > i mean, what is "1" doing here ? and why (ix) rather than [ix] ? i am
    > at halfway of chapter 3 so i have not come across this "append" member
    > function. just covered "size" and "empty" till yet.


    RTFM. 'append' is overloaded and one of them takes a number (N) and
    the character and appends a string generated from N characters. There
    is a constructor that does similar stuff, BTW.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jul 18, 2007
    #7
  8. arnuld

    arnuld Guest

    > On Wed, 18 Jul 2007 12:04:02 +0200, anon wrote:

    > Here is the fixed (hack) version:


    :)

    > #include <iostream>
    > #include <string>
    >
    > int main()
    > {
    > std::cout << "Enter a string: ";
    > std::string a_word, stripped_word;
    > std::cin >> a_word;
    >
    > for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    > {
    > if(ispunct(a_word.at(ix)) == 0)
    > stripped_word.append(1,a_word.at(ix));
    > }
    >
    > std::cout << stripped_word << std::endl;
    >
    > return 0;



    can you tell me how this works or just point me to someplave which
    explains that:

    stripped_word.append(1,a_word.at(ix));

    i mean, what is "1" doing here ? and why (ix) rather than [ix] ? i am at
    halfway of chapter 3 so i have not come across this "append" member
    function. just covered "size" and "empty" till yet.




    --
    -- http://arnuld.blogspot.com
    arnuld, Jul 18, 2007
    #8
  9. arnuld

    anon Guest

    Victor Bazarov wrote:
    > arnuld wrote:
    >> [..]
    >> can you tell me how this works or just point me to someplave which
    >> explains that:
    >>
    >> stripped_word.append(1,a_word.at(ix));
    >>
    >> i mean, what is "1" doing here ? and why (ix) rather than [ix] ? i am
    >> at halfway of chapter 3 so i have not come across this "append" member
    >> function. just covered "size" and "empty" till yet.

    >
    > RTFM. 'append' is overloaded and one of them takes a number (N) and
    > the character and appends a string generated from N characters. There
    > is a constructor that does similar stuff, BTW.


    These guys got very good references:
    http://www.cppreference.com/cppstring/index.html
    and should answer all questions.


    PS If anyone know better references, please let me know.
    www.cppreference.com is missing lots of stuff
    anon, Jul 18, 2007
    #9
  10. On 2007-07-18 18:17, anon wrote:
    > Victor Bazarov wrote:
    >> arnuld wrote:
    >>> [..]
    >>> can you tell me how this works or just point me to someplave which
    >>> explains that:
    >>>
    >>> stripped_word.append(1,a_word.at(ix));
    >>>
    >>> i mean, what is "1" doing here ? and why (ix) rather than [ix] ? i am
    >>> at halfway of chapter 3 so i have not come across this "append" member
    >>> function. just covered "size" and "empty" till yet.

    >>
    >> RTFM. 'append' is overloaded and one of them takes a number (N) and
    >> the character and appends a string generated from N characters. There
    >> is a constructor that does similar stuff, BTW.

    >
    > These guys got very good references:
    > http://www.cppreference.com/cppstring/index.html
    > and should answer all questions.
    >
    >
    > PS If anyone know better references, please let me know.
    > www.cppreference.com is missing lots of stuff


    www.cplusplus.com is quite complete I think, but I like the simplicity
    of www.cppreference.com better.

    --
    Erik Wikström
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=, Jul 18, 2007
    #10
  11. arnuld

    red floyd Guest

    arnuld wrote:
    > /* C++ Primer 4/e
    > * section 3.2 - String Standard Library
    >
    > * exercise 3.10
    > * STATEMENT
    > * write a programme to strip the punctation from the string. */
    >
    > #include <iostream>
    > #include <string>
    >
    > int main()
    > {
    > std::cout << "Enter a string: ";
    > std::string a_word, stripped_word;
    > std::cin >> a_word;
    >
    > for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    > {
    > if(ispunct(a_word[ix]) == 0)
    > stripped_word[ix] = a_word[ix];
    > }
    >
    > std::cout << stripped_word << std::endl;
    >
    > return 0;
    > }
    >



    Don't you also need to #include <cctype> for ispunct()?
    red floyd, Jul 18, 2007
    #11
  12. arnuld

    BobR Guest

    arnuld <> wrote in message...
    > /* C++ Primer 4/e * section 3.2 - String Standard Library
    > * exercise 3.10
    > * STATEMENT
    > * write a programme to strip the punctation from the string. */
    >
    > #include <iostream>
    > #include <string>
    > int main(){
    > std::cout << "Enter a string: ";
    > std::string a_word, stripped_word;
    > std::cin >> a_word;
    > for(std::string::size_type ix = 0; ix != a_word.size(); ++ix){
    > if(ispunct(a_word[ix]) == 0)
    > stripped_word[ix] = a_word[ix];
    > }
    > std::cout << stripped_word << std::endl;
    > return 0;
    > }
    >


    Another way than shown already (push_back()):

    #include <iostream>
    #include <string>
    #include <cctype>

    int main(){
    std::string a_word("I think, therefore, I am! I'm shocked?");
    // std::cout << "Enter a string: ";
    // std::cin >> a_word;
    std::cout<<"a_word="<<a_word<<std::endl;

    std::string stripped_word;
    for( std::string::size_type ix = 0; ix != a_word.size(); ++ix){
    if( not std::ispunct( a_word.at( ix ) ) )
    stripped_word.push_back( a_word.at( ix ) );
    }

    std::cout<<"stripped_word="<<stripped_word<<std::endl;
    return 0;
    }
    // out:a_word=I think, therefore, I am! I'm shocked?
    // out:stripped_word=I think therefore I am Im shocked

    --
    Bob R
    POVrookie
    BobR, Jul 18, 2007
    #12
  13. arnuld

    James Kanze Guest

    On Jul 18, 12:53 pm, Ian Collins <> wrote:
    > arnuld wrote:
    > > /* C++ Primer 4/e
    > > * section 3.2 - String Standard Library


    > > * exercise 3.10
    > > * STATEMENT
    > > * write a programme to strip the punctation from the string. */


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


    > > int main()
    > > {
    > > std::cout << "Enter a string: ";
    > > std::string a_word, stripped_word;
    > > std::cin >> a_word;


    > > for(std::string::size_type ix = 0; ix != a_word.size(); ++ix)
    > > {
    > > if(ispunct(a_word[ix]) == 0)
    > > stripped_word[ix] = a_word[ix];
    > > }


    > > std::cout << stripped_word << std::endl;
    > > return 0;
    > > }


    > As well as the other suggestions, you could use:


    > for( std::string::const_iterator ix = a_word.begin();
    > ix != a_word.end(); ++ix )
    > {
    > if(ispunct(*ix) == 0)
    > stripped_word += *ix;
    > }


    That's getting close to what I would write. Except that the one
    argument form of ispunct requires an include of <ctype.h>, and
    it's undefined behavior to use it directly on a char. For a
    quick program, without using any of my existing toolset, I'd
    write:

    if ( ! ispunct( static_cast< unsigned char >( *ix ) ) {
    stripped_word += *ix ;
    }

    in the loop. With my usual tools, I'd more likely write:

    word.erase( std::remove( word.begin(), word.end(),
    CTypeIs( std::ctype_base::punct )),
    word.end() ) ;

    and be done with it. But this only works because I've got the
    function objects to wrap std::ctype<char> in my standard
    toolbox. Otherwise, you have to write a special class to do
    this, which is a bit of a drag.

    --
    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 19, 2007
    #13
  14. arnuld

    Jerry Coffin Guest

    In article <>,
    says...

    [ ... ]

    > As well as the other suggestions, you could use:
    >
    > for( std::string::const_iterator ix = a_word.begin();
    > ix != a_word.end(); ++ix )
    > {
    > if(ispunct(*ix) == 0)
    > stripped_word += *ix;
    > }


    Or:

    std::remove_copy_if(a_word.begin(), a_word.end(),
    std::back_inserter(stripped_word), ispunct);

    Of course, to be correct you really can't apply ispunct directly to
    chars. Something like this should fix that:

    struct punct {
    bool operator()(char ch) {
    return ispunct((unsigned char)ch);
    }
    };

    then the same algorithm, but using that functor:

    std::remove_copy_if(a_word.begin(), a_word.end(),
    std::back_inserter(stripped_word), punct());

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Jul 23, 2007
    #14
    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. Ioannis Vranos

    ispunct()

    Ioannis Vranos, May 1, 2004, in forum: C++
    Replies:
    11
    Views:
    2,481
    Keith Thompson
    May 4, 2004
  2. Peter Jansson
    Replies:
    5
    Views:
    6,300
    Ivan Vecerina
    Mar 17, 2005
  3. Ioannis Vranos

    ispunct()

    Ioannis Vranos, May 1, 2004, in forum: C Programming
    Replies:
    11
    Views:
    710
    Keith Thompson
    May 4, 2004
  4. Fei Liu
    Replies:
    9
    Views:
    440
  5. Jeffrey Walton
    Replies:
    10
    Views:
    938
    Mathias Gaunard
    Nov 26, 2006
Loading...

Share This Page