atoi()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Christopher Benson-Manica

    atoi()

    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)cybers pace.org | don't, I need to know. Flames welcome.
  • Jonathan Turkanis

    #2
    Re: atoi()

    "Christophe r Benson-Manica" <ataru@nospam.c yberspace.org> wrote in
    message news:bu6uga$rjv $1@chessie.cirr .com...[color=blue]
    > What is the preferred C++ alternative to C's atoi(), if there is[/color]
    one?[color=blue]
    >
    > --
    > Christopher Benson-Manica | I *should* know what I'm talking[/color]
    about - if I[color=blue]
    > ataru(at)cybers pace.org | don't, I need to know. Flames welcome.[/color]

    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


    Comment

    • Christopher Benson-Manica

      #3
      Re: atoi()

      Jonathan Turkanis <technews@kanga roologic.com> spoke thus:
      [color=blue]
      > The standard alternative is to construct a stringstream and read its
      > data into an int using >>.[/color]

      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)cybers pace.org | don't, I need to know. Flames welcome.

      Comment

      • Kevin Goodsell

        #4
        Re: atoi()

        Christopher Benson-Manica wrote:[color=blue]
        > Jonathan Turkanis <technews@kanga roologic.com> spoke thus:
        >
        >[color=green]
        >>The standard alternative is to construct a stringstream and read its
        >>data into an int using >>.[/color]
        >
        >
        > 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?[/color]

        You forgot std::.
        [color=blue]
        > }
        > return EXIT_SUCCESS;
        > }
        >[/color]

        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.

        Comment

        • Jonathan Turkanis

          #5
          Re: atoi()

          "Christophe r Benson-Manica" <ataru@nospam.c yberspace.org> wrote in
          message news:bu705v$rnu $1@chessie.cirr .com...[color=blue]
          > Jonathan Turkanis <technews@kanga roologic.com> spoke thus:
          >[color=green]
          > > The standard alternative is to construct a stringstream and read[/color][/color]
          its[color=blue][color=green]
          > > data into an int using >>.[/color]
          >
          > 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;
          > }
          >[/color]

          int main( int argc, char *argv[] )
          {
          int count=0;
          if( argc > 1 && (std::stringstr eam(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



          Comment

          • Ron Natalie

            #6
            Re: atoi()


            "Christophe r Benson-Manica" <ataru@nospam.c yberspace.org> wrote in message news:bu6uga$rjv $1@chessie.cirr .com...[color=blue]
            > What is the preferred C++ alternative to C's atoi(), if there is one?
            >[/color]
            I won't even use atoi in C. There are input conditions that cause it to
            invoke undefined behavior. strtol is much better behaved.

            Comment

            • Norbert Riedlin

              #7
              Re: atoi()

              "Christophe r Benson-Manica" <ataru@nospam.c yberspace.org> schrieb im
              Newsbeitrag news:bu705v$rnu $1@chessie.cirr .com...[color=blue]
              > Jonathan Turkanis <technews@kanga roologic.com> 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;
              > }
              >[/color]

              What is the difference?

              #include <boost/lexical_cast.hp p> // #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_lexi cal_cast but...

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

              Bye

              Norbert



              Comment

              • Jonathan Turkanis

                #8
                Re: atoi()

                "Norbert Riedlin" <norbert.riedli n@t-online.de> wrote in message
                news:bu74gg$a6q $06$1@news.t-online.com...[color=blue]
                > "Christophe r Benson-Manica" <ataru@nospam.c yberspace.org> schrieb im
                > Newsbeitrag news:bu705v$rnu $1@chessie.cirr .com...[color=green]
                > > Jonathan Turkanis <technews@kanga roologic.com> 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;
                > > }
                > >[/color]
                >
                > What is the difference?
                >
                > #include <boost/lexical_cast.hp p> // #include <cstdlib>
                >
                > int main( int argc, char *argv[] )
                > {
                > int count=0;
                > if( argc > 1 ) {
                > count = boost::lexical_ cast<int>(argv[1]); // count=atoi([/color]
                argv[1] );[color=blue]
                > }
                > // 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_lexi cal_cast but...
                >
                > In my opinion, lexical_cast is to be preferred in _any_ realistical
                > case. In not realistical cases, noone cares.
                >[/color]

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

                Jonathan


                Comment

                • Norbert Riedlin

                  #9
                  Re: atoi()


                  "Jonathan Turkanis" <technews@kanga roologic.com> schrieb im Newsbeitrag
                  news:bu74qk$ebe 1i$1@ID-216073.news.uni-berlin.de...[color=blue]
                  > "Norbert Riedlin" <norbert.riedli n@t-online.de> wrote in message
                  > news:bu74gg$a6q $06$1@news.t-online.com...[color=green]
                  > > "Christophe r Benson-Manica" <ataru@nospam.c yberspace.org> schrieb im
                  > > Newsbeitrag news:bu705v$rnu $1@chessie.cirr .com...[/color]
                  >
                  >
                  > Do we disagree on anything? I mentioned the 'standard C++ alternative'
                  > as well as boost::lexical cast; I did not express any preference.
                  >
                  > Jonathan
                  >[/color]
                  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


                  Comment

                  • Peter Koch Larsen

                    #10
                    Re: atoi()


                    "Norbert Riedlin" <norbert.riedli n@t-online.de> skrev i en meddelelse
                    news:bu74gg$a6q $06$1@news.t-online.com...[color=blue]
                    > "Christophe r Benson-Manica" <ataru@nospam.c yberspace.org> schrieb im
                    > Newsbeitrag news:bu705v$rnu $1@chessie.cirr .com...[color=green]
                    > > Jonathan Turkanis <technews@kanga roologic.com> 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;
                    > > }
                    > >[/color]
                    >
                    > What is the difference?
                    >
                    > #include <boost/lexical_cast.hp p> // #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_lexi cal_cast but...
                    >
                    > In my opinion, lexical_cast is to be preferred in _any_ realistical
                    > case. In not realistical cases, noone cares.
                    >
                    > Bye
                    >
                    > Norbert
                    >[/color]

                    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


                    Comment

                    • Nick Hounsome

                      #11
                      Re: atoi()


                      "Christophe r Benson-Manica" <ataru@nospam.c yberspace.org> wrote in message
                      news:bu6uga$rjv $1@chessie.cirr .com...[color=blue]
                      > What is the preferred C++ alternative to C's atoi(), if there is one?
                      >[/color]

                      - 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

                      [color=blue]
                      > --
                      > Christopher Benson-Manica | I *should* know what I'm talking about - if I
                      > ataru(at)cybers pace.org | don't, I need to know. Flames welcome.[/color]


                      Comment

                      • Jeff Schwab

                        #12
                        Re: atoi()

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

                        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';
                        }
                        }

                        Comment

                        • Ron Natalie

                          #13
                          Re: atoi()


                          "Nick Hounsome" <nh002@blueyond er.co.uk> wrote in message news:zTPNb.2642 $pD3.311@news-binary.blueyond er.co.uk...[color=blue]
                          > - std::strtol is also standard C and standard C++ and is superior in every
                          > respect ( IMHO atoi should be deprecated ).[/color]

                          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."

                          Comment

                          • Norbert Riedlin

                            #14
                            Re: atoi()


                            "Jeff Schwab" <jeffplus@comca st.net> schrieb im Newsbeitrag
                            news:o5-dnXnXd-tgfZrdRVn-jQ@comcast.com. ..[color=blue]
                            > 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;
                            > }
                            >[/color]
                            You are asuming the ASCII character set? In EBCDIC '9' > 'a'.

                            Bye

                            Norbert


                            Comment

                            • Jeff Schwab

                              #15
                              Re: atoi()

                              Norbert Riedlin wrote:[color=blue]
                              > "Jeff Schwab" <jeffplus@comca st.net> schrieb im Newsbeitrag
                              > news:o5-dnXnXd-tgfZrdRVn-jQ@comcast.com. ..
                              >[color=green]
                              >>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;
                              >>}
                              >>[/color]
                              >
                              > You are asuming the ASCII character set? In EBCDIC '9' > 'a'.
                              >
                              > Bye
                              >
                              > Norbert
                              >
                              >[/color]


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

                              '0' <= *p && *p <= '9'

                              Comment

                              Working...