atoi()

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

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

Christopher Benson-Manica

Jonathan Turkanis said:
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;
}
 
K

Kevin Goodsell

Christopher said:
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
 
J

Jonathan Turkanis

Christopher Benson-Manica said:
Jonathan Turkanis said:
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
 
R

Ron Natalie

Christopher Benson-Manica said:
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.
 
N

Norbert Riedlin

Christopher Benson-Manica said:
Jonathan Turkanis <[email protected]> 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
 
J

Jonathan Turkanis

Norbert Riedlin said:
Christopher Benson-Manica said:
Jonathan Turkanis <[email protected]> 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
 
N

Norbert Riedlin

Jonathan Turkanis said:
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
 
P

Peter Koch Larsen

Norbert Riedlin said:
Christopher Benson-Manica said:
Jonathan Turkanis <[email protected]> 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
 
N

Nick Hounsome

Christopher Benson-Manica said:
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

 
J

Jeff Schwab

Christopher said:
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';
}
}
 
R

Ron Natalie

Nick Hounsome said:
- 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."
 
N

Norbert Riedlin

Jeff Schwab said:
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
 
J

Jeff Schwab

Norbert said:
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'
 
N

Norbert Riedlin

Jeff Schwab said:
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
 
J

Jeff Schwab

Norbert said:
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."
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Print with command-line arguments 0
Kotlin Thread 0
problematic atoi conversion 2
Help with Char* (i.e. c = atoi(year+2)) 25
a question abou "atoi" 6
integer overflow in atoi 29
atoi/atof 14
C format programs 17

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top