atoi()

Discussion in 'C++' started by Christopher Benson-Manica, Jan 15, 2004.

  1. What is the preferred C++ alternative to C's atoi(), if there is one?

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    Christopher Benson-Manica, Jan 15, 2004
    #1
    1. Advertising

  2. "Christopher Benson-Manica" <> wrote in
    message news:bu6uga$rjv$...
    > What is the preferred C++ alternative to C's atoi(), if there is

    one?
    >
    > --
    > Christopher Benson-Manica | I *should* know what I'm talking

    about - if I
    > ataru(at)cyberspace.org | don't, I need to know. Flames welcome.


    The standard alternative is to construct a stringstream and read its
    data into an int using >>. See also
    http://www.boost.org/libs/conversion/lexical_cast.htm.

    Jonathan
    Jonathan Turkanis, Jan 15, 2004
    #2
    1. Advertising

  3. Jonathan Turkanis <> spoke thus:

    > The standard alternative is to construct a stringstream and read its
    > data into an int using >>.


    You would recommend such an approach in the following situation?

    #include <cstdlib>

    int main( int argc, char *argv[] )
    {
    int count=0;
    if( argc > 1 ) {
    count=atoi( argv[1] ); // <- worth setting up a stringstream?
    }
    return EXIT_SUCCESS;
    }

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    Christopher Benson-Manica, Jan 15, 2004
    #3
  4. Christopher Benson-Manica wrote:
    > Jonathan Turkanis <> spoke thus:
    >
    >
    >>The standard alternative is to construct a stringstream and read its
    >>data into an int using >>.

    >
    >
    > You would recommend such an approach in the following situation?
    >
    > #include <cstdlib>
    >
    > int main( int argc, char *argv[] )
    > {
    > int count=0;
    > if( argc > 1 ) {
    > count=atoi( argv[1] ); // <- worth setting up a stringstream?


    You forgot std::.

    > }
    > return EXIT_SUCCESS;
    > }
    >


    Well, atoi() doesn't allow much in the way of error detection &
    recovery. It silently invokes undefined behavior on overflow, if I
    recall correctly. I'd recommend using either the stringstream method or
    possibly strtol() or a related function - whichever you think is
    appropriate for the situation.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Jan 15, 2004
    #4
  5. "Christopher Benson-Manica" <> wrote in
    message news:bu705v$rnu$...
    > Jonathan Turkanis <> spoke thus:
    >
    > > The standard alternative is to construct a stringstream and read

    its
    > > data into an int using >>.

    >
    > You would recommend such an approach in the following situation?
    >
    > #include <cstdlib>
    >
    > int main( int argc, char *argv[] )
    > {
    > int count=0;
    > if( argc > 1 ) {
    > count=atoi( argv[1] ); // <- worth setting up a stringstream?
    > }
    > return EXIT_SUCCESS;
    > }
    >


    int main( int argc, char *argv[] )
    {
    int count=0;
    if( argc > 1 && (std::stringstream(argv[1]) >> count) )
    /* ... */
    }
    return EXIT_SUCCESS;
    }

    There is a certain overhead to using a stringstream or stringbuf:
    constuction of a locale, and depending on the implementation,
    initialization of a number of member pointers and possibly a
    synchronization construct. So its not appropriate always. It is,
    however, the 'standard C++ alternative.'

    Jonathan
    Jonathan Turkanis, Jan 15, 2004
    #5
  6. Christopher Benson-Manica

    Ron Natalie Guest

    "Christopher Benson-Manica" <> wrote in message news:bu6uga$rjv$...
    > What is the preferred C++ alternative to C's atoi(), if there is one?
    >

    I won't even use atoi in C. There are input conditions that cause it to
    invoke undefined behavior. strtol is much better behaved.
    Ron Natalie, Jan 15, 2004
    #6
  7. "Christopher Benson-Manica" <> schrieb im
    Newsbeitrag news:bu705v$rnu$...
    > Jonathan Turkanis <> spoke thus:
    >
    > #include <cstdlib>
    >
    > int main( int argc, char *argv[] )
    > {
    > int count=0;
    > if( argc > 1 ) {
    > count=atoi( argv[1] ); // <- worth setting up a stringstream?
    > }
    > return EXIT_SUCCESS;
    > }
    >


    What is the difference?

    #include <boost/lexical_cast.hpp> // #include <cstdlib>

    int main( int argc, char *argv[] )
    {
    int count=0;
    if( argc > 1 ) {
    count = boost::lexical_cast<int>(argv[1]); // count=atoi( argv[1] );
    }
    // return EXIT_SUCCESS;
    }

    Why should one _not_ use lexical_cast in this/any case? Ok, to
    have the same result here you had to surround the cast by a try
    block, catching the appropriate boost::bad_lexical_cast but...

    In my opinion, lexical_cast is to be preferred in _any_ realistical
    case. In not realistical cases, noone cares.

    Bye

    Norbert
    Norbert Riedlin, Jan 15, 2004
    #7
  8. "Norbert Riedlin" <> wrote in message
    news:bu74gg$a6q$06$-online.com...
    > "Christopher Benson-Manica" <> schrieb im
    > Newsbeitrag news:bu705v$rnu$...
    > > Jonathan Turkanis <> spoke thus:
    > >
    > > #include <cstdlib>
    > >
    > > int main( int argc, char *argv[] )
    > > {
    > > int count=0;
    > > if( argc > 1 ) {
    > > count=atoi( argv[1] ); // <- worth setting up a stringstream?
    > > }
    > > return EXIT_SUCCESS;
    > > }
    > >

    >
    > What is the difference?
    >
    > #include <boost/lexical_cast.hpp> // #include <cstdlib>
    >
    > int main( int argc, char *argv[] )
    > {
    > int count=0;
    > if( argc > 1 ) {
    > count = boost::lexical_cast<int>(argv[1]); // count=atoi(

    argv[1] );
    > }
    > // return EXIT_SUCCESS;
    > }
    >
    > Why should one _not_ use lexical_cast in this/any case? Ok, to
    > have the same result here you had to surround the cast by a try
    > block, catching the appropriate boost::bad_lexical_cast but...
    >
    > In my opinion, lexical_cast is to be preferred in _any_ realistical
    > case. In not realistical cases, noone cares.
    >


    Do we disagree on anything? I mentioned the 'standard C++ alternative'
    as well as boost::lexical cast; I did not express any preference.

    Jonathan
    Jonathan Turkanis, Jan 15, 2004
    #8
  9. "Jonathan Turkanis" <> schrieb im Newsbeitrag
    news:bu74qk$ebe1i$-berlin.de...
    > "Norbert Riedlin" <> wrote in message
    > news:bu74gg$a6q$06$-online.com...
    > > "Christopher Benson-Manica" <> schrieb im
    > > Newsbeitrag news:bu705v$rnu$...

    >
    >
    > Do we disagree on anything? I mentioned the 'standard C++ alternative'
    > as well as boost::lexical cast; I did not express any preference.
    >
    > Jonathan
    >

    Not at all. If you look closer, I was relying to Christopher's post. I
    should have
    been more careful cutting the posting though...

    Bye

    Norbert
    Norbert Riedlin, Jan 15, 2004
    #9
  10. "Norbert Riedlin" <> skrev i en meddelelse
    news:bu74gg$a6q$06$-online.com...
    > "Christopher Benson-Manica" <> schrieb im
    > Newsbeitrag news:bu705v$rnu$...
    > > Jonathan Turkanis <> spoke thus:
    > >
    > > #include <cstdlib>
    > >
    > > int main( int argc, char *argv[] )
    > > {
    > > int count=0;
    > > if( argc > 1 ) {
    > > count=atoi( argv[1] ); // <- worth setting up a stringstream?
    > > }
    > > return EXIT_SUCCESS;
    > > }
    > >

    >
    > What is the difference?
    >
    > #include <boost/lexical_cast.hpp> // #include <cstdlib>
    >
    > int main( int argc, char *argv[] )
    > {
    > int count=0;
    > if( argc > 1 ) {
    > count = boost::lexical_cast<int>(argv[1]); // count=atoi( argv[1] );
    > }
    > // return EXIT_SUCCESS;
    > }
    >
    > Why should one _not_ use lexical_cast in this/any case? Ok, to
    > have the same result here you had to surround the cast by a try
    > block, catching the appropriate boost::bad_lexical_cast but...
    >
    > In my opinion, lexical_cast is to be preferred in _any_ realistical
    > case. In not realistical cases, noone cares.
    >
    > Bye
    >
    > Norbert
    >


    While I would agree with you in the general case, there could be cases where
    avoiding streams would better be avoided. One example is when you write a
    program where you are concerned about its footprint: if that program only
    uses streams this one place, it does justify using an alternative approach.

    Kind regards
    Peter
    Peter Koch Larsen, Jan 16, 2004
    #10
  11. "Christopher Benson-Manica" <> wrote in message
    news:bu6uga$rjv$...
    > What is the preferred C++ alternative to C's atoi(), if there is one?
    >


    - std::atoi is standard C++
    - std::strtol is also standard C and standard C++ and is superior in every
    respect ( IMHO atoi should be deprecated ).
    - You could use an istrstream but why bother?
    - I can think of no good reason to use an istringstream if you have a char*.

    - as far as I am aware there is no stream equivalent of the strtol ability
    to read numbers in decimal,octal or hex


    > --
    > Christopher Benson-Manica | I *should* know what I'm talking about - if I
    > ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    Nick Hounsome, Jan 16, 2004
    #11
  12. Christopher Benson-Manica

    Jeff Schwab Guest

    Christopher Benson-Manica wrote:
    > What is the preferred C++ alternative to C's atoi(), if there is one?
    >


    I rolled my own alternative. The idea is this, but if you're looking
    for an improvement over atoi, you might consider validating the pointer,
    the base, and the digits.


    template< typename N > // unsigned numeric type
    N ato( char const* p, unsigned base =10 )
    {
    N result = N( );

    while( *p )
    {
    result = result * base + ( *p <= '9' ? *p - '0' : *p - 'a' + 10 );
    ++p;
    }

    return result;
    }

    #include <iostream>

    int main( int argc, char *argv[] )
    {
    if( argc > 1 )
    {
    unsigned base = 10;

    if( argc > 2 )
    {
    base = ato< unsigned >( argv[ 2 ] );
    }

    std::cout << ato< int >( argv[ 1 ], base ) << '\n';
    }
    }
    Jeff Schwab, Jan 16, 2004
    #12
  13. Christopher Benson-Manica

    Ron Natalie Guest

    "Nick Hounsome" <> wrote in message news:zTPNb.2642$...
    > - std::strtol is also standard C and standard C++ and is superior in every
    > respect ( IMHO atoi should be deprecated ).


    In my opinion, it could just be fixed by requiring it to be defined as:
    int atoi(const char* s) { return strtol(s, 0, 10); }

    That is, change it from undefined behavior to implementation defined value on
    overflow. C99 even includes the above snippet as the definition "except for error
    behavior."
    Ron Natalie, Jan 16, 2004
    #13
  14. "Jeff Schwab" <> schrieb im Newsbeitrag
    news:eek:...
    > template< typename N > // unsigned numeric type
    > N ato( char const* p, unsigned base =10 )
    > {
    > N result = N( );
    >
    > while( *p )
    > {
    > result = result * base + ( *p <= '9' ? *p - '0' : *p - 'a' + 10 );
    > ++p;
    > }
    >
    > return result;
    > }
    >

    You are asuming the ASCII character set? In EBCDIC '9' > 'a'.

    Bye

    Norbert
    Norbert Riedlin, Jan 16, 2004
    #14
  15. Christopher Benson-Manica

    Jeff Schwab Guest

    Norbert Riedlin wrote:
    > "Jeff Schwab" <> schrieb im Newsbeitrag
    > news:eek:...
    >
    >>template< typename N > // unsigned numeric type
    >>N ato( char const* p, unsigned base =10 )
    >>{
    >> N result = N( );
    >>
    >> while( *p )
    >> {
    >> result = result * base + ( *p <= '9' ? *p - '0' : *p - 'a' + 10 );
    >> ++p;
    >> }
    >>
    >> return result;
    >>}
    >>

    >
    > You are asuming the ASCII character set? In EBCDIC '9' > 'a'.
    >
    > Bye
    >
    > Norbert
    >
    >



    No assumption, just a mistake. That should have said:

    '0' <= *p && *p <= '9'
    Jeff Schwab, Jan 17, 2004
    #15
  16. "Jeff Schwab" <> schrieb im Newsbeitrag
    news:...
    > Norbert Riedlin wrote:
    > > "Jeff Schwab" <> schrieb im Newsbeitrag
    > > news:eek:...
    > >
    > >>template< typename N > // unsigned numeric type
    > >>N ato( char const* p, unsigned base =10 )
    > >>{
    > >> N result = N( );
    > >>
    > >> while( *p )
    > >> {
    > >> result = result * base + ( *p <= '9' ? *p - '0' : *p - 'a' + 10 );
    > >> ++p;
    > >> }
    > >>
    > >> return result;
    > >>}
    > >>

    > >
    > > You are asuming the ASCII character set? In EBCDIC '9' > 'a'.
    > >

    >
    > No assumption, just a mistake. That should have said:
    >
    > '0' <= *p && *p <= '9'
    >

    Ok, so you are asuming correct and all lowercase input?

    Bye Norbert
    Norbert Riedlin, Jan 18, 2004
    #16
  17. Christopher Benson-Manica

    Jeff Schwab Guest

    Norbert Riedlin wrote:
    > "Jeff Schwab" <> schrieb im Newsbeitrag
    > news:...
    >
    >>Norbert Riedlin wrote:
    >>
    >>>"Jeff Schwab" <> schrieb im Newsbeitrag
    >>>news:eek:...
    >>>
    >>>
    >>>>template< typename N > // unsigned numeric type
    >>>>N ato( char const* p, unsigned base =10 )
    >>>>{
    >>>> N result = N( );
    >>>>
    >>>> while( *p )
    >>>> {
    >>>> result = result * base + ( *p <= '9' ? *p - '0' : *p - 'a' + 10 );
    >>>> ++p;
    >>>> }
    >>>>
    >>>> return result;
    >>>>}
    >>>>
    >>>
    >>>You are asuming the ASCII character set? In EBCDIC '9' > 'a'.
    >>>

    >>
    >>No assumption, just a mistake. That should have said:
    >>
    >> '0' <= *p && *p <= '9'
    >>

    >
    > Ok, so you are asuming correct and all lowercase input?
    >
    > Bye Norbert


    Are you unable to read? Here's the part of my post you snipped.

    "The idea is this, but if you're looking for an improvement over atoi,
    you might consider validating the pointer, the base, and the digits."
    Jeff Schwab, Jan 18, 2004
    #17
    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. lonelyplanet999
    Replies:
    8
    Views:
    42,912
  2. Magig Boatman
    Replies:
    1
    Views:
    460
    Russell Hanneken
    Jul 11, 2003
  3. Mike Chirico
    Replies:
    2
    Views:
    3,818
    Grumble
    Nov 19, 2003
  4. Neil Vice

    Re: atoi - please help

    Neil Vice, Apr 1, 2004, in forum: C++
    Replies:
    0
    Views:
    353
    Neil Vice
    Apr 1, 2004
  5. senthil kumar

    PPC and atoi

    senthil kumar, May 1, 2004, in forum: C++
    Replies:
    4
    Views:
    449
    John Harrison
    May 2, 2004
Loading...

Share This Page