Standard Library function converting char[] to int?

S

Steven T. Hatton

I know I can write one, or use QString, etc., but is there a native C++
function to convert a NTBS of digits to an integer?
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
C

Chris \( Val \)

|I know I can write one, or use QString, etc., but is there a native C++
| function to convert a NTBS of digits to an integer?

[snip]

For straight out of the box, the following will do:

// Non-Preferred...
'std::atoi()'

// Much-Preferred...
'std::strtol()' and 'std::strtoul()'

Cheers.
Chris Val
 
S

Steven T. Hatton

Chris said:
|I know I can write one, or use QString, etc., but is there a native C++
| function to convert a NTBS of digits to an integer?

[snip]

For straight out of the box, the following will do:

// Non-Preferred...
'std::atoi()'

// Much-Preferred...
'std::strtol()' and 'std::strtoul()'

Cheers.
Chris Val

Thanks. I should have looked in K&R. Have a good laugh at my expense:

size_t ntbs2size_t(char* intStr) {
size_t result = 0;

while (*intStr != 0) {
if(!isdigit(*intStr))
{
throw invalid_argument("cstr2size_t: argument not a digit.\n");
}

result = (result * 10) + (*intStr - '0');
intStr++;
}
return result;
}

--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
B

Bob Hairgrove

I know I can write one, or use QString, etc., but is there a native C++
function to convert a NTBS of digits to an integer?

Depends on whether the string represents an integer which fits into
the integer supported by your system.

Neither strtol nor strtod are "native C++ functions", but functions
defined by the C runtime library. Of course, strtol will also fail if
the string is too large.

Anyway, here is a purely C++ solution using the STL:

#include <iostream>
#include <ostream>
#include <sstream>

int main()
{
using namespace std;
int a;
char const * pc = "1234567890";
std::istringstream iss(pc);
iss >> a;
cout << "Number is: " << a << endl;
return 0;
}
 
V

Victor Bazarov

Steven said:
[...] Have a good laugh at my expense:

size_t ntbs2size_t(char* intStr) {

Better to declare the argument as 'const char*'. And you never check
the 'intStr' for being null either. But that's OK if you document
that your function has UB if a null pointer is passed to it.
size_t result = 0;

while (*intStr != 0) {
if(!isdigit(*intStr))
{
throw invalid_argument("cstr2size_t: argument not a digit.\n");
}

result = (result * 10) + (*intStr - '0');
intStr++;
}
return result;
}

Hey, that's not all that bad an implementation of 'atoi'. Has some error
checking as well.

V
 
C

Chris \( Val \)

| On Fri, 22 Oct 2004 08:52:08 -0400, "Steven T. Hatton"
|
| >I know I can write one, or use QString, etc., but is there a native C++
| >function to convert a NTBS of digits to an integer?
|
| Depends on whether the string represents an integer which fits into
| the integer supported by your system.
|
| Neither strtol nor strtod are "native C++ functions", but functions
| defined by the C runtime library. Of course, strtol will also fail if
| the string is too large.
|
| Anyway, here is a purely C++ solution using the STL:
|
| #include <iostream>
| #include <ostream>
| #include <sstream>
|
| int main()
| {
| using namespace std;
| int a;
| char const * pc = "1234567890";
| std::istringstream iss(pc);
| iss >> a;
| cout << "Number is: " << a << endl;
| return 0;
| }

If you want that to work safely, then you'll need
to add some error checking, otherwise it too can
fail miserably.

Cheers.
Chris Val
 
B

Bob Hairgrove

| On Fri, 22 Oct 2004 08:52:08 -0400, "Steven T. Hatton"
|
| >I know I can write one, or use QString, etc., but is there a native C++
| >function to convert a NTBS of digits to an integer?
|
| Depends on whether the string represents an integer which fits into
| the integer supported by your system.
|
| Neither strtol nor strtod are "native C++ functions", but functions
| defined by the C runtime library. Of course, strtol will also fail if
| the string is too large.
|
| Anyway, here is a purely C++ solution using the STL:
|
| #include <iostream>
| #include <ostream>
| #include <sstream>
|
| int main()
| {
| using namespace std;
| int a;
| char const * pc = "1234567890";
| std::istringstream iss(pc);
| iss >> a;
| cout << "Number is: " << a << endl;
| return 0;
| }

If you want that to work safely, then you'll need
to add some error checking, otherwise it too can
fail miserably.

Hmm ... just tried a huge number. I thought that if the number
represented by the string were too large, istream::eek:perator>> should
throw an exception. But it doesn't!

Here's an improved version:

#include <iostream>
#include <ostream>
#include <sstream>
#include <stdexcept>
#include <limits>

int main()
{
using namespace std;
try
{
int a;
double d;
char const * pc = "12345678901234567890";
std::istringstream iss(pc);
iss >> d;
if (d <= numeric_limits<int>::max()
&& d >= numeric_limits<int>::min())
{
a = static_cast<int>(d);
cout << "Number is: " << a << endl;
}
else
{
cout << "Error: number " << iss.str();
cout << " is out of range for int." << endl;
}
}
catch(const std::exception &e)
{
cout << "Error: " << e.what() << endl;
}
return 0;
}
 
C

Chris \( Val \)

| On Sat, 23 Oct 2004 19:34:38 +1000, "Chris \( Val \)"

[snip]

| >| int main()
| >| {
| >| using namespace std;
| >| int a;
| >| char const * pc = "1234567890";
| >| std::istringstream iss(pc);
| >| iss >> a;
| >| cout << "Number is: " << a << endl;
| >| return 0;
| >| }
| >
| >If you want that to work safely, then you'll need
| >to add some error checking, otherwise it too can
| >fail miserably.
|
| Hmm ... just tried a huge number. I thought that if the number
| represented by the string were too large, istream::eek:perator>> should
| throw an exception. But it doesn't!

That will only happen if you turn 'istream::exceptions()'
on manually, by setting the appropriate bit mask(s), but
it is not always ideal, and still requires further code
to make it safe, I think.

| Here's an improved version:
|
| #include <iostream>
| #include <ostream>
| #include <sstream>
| #include <stdexcept>
| #include <limits>
|
| int main()
| {
| using namespace std;
| try
| {
| int a;
| double d;
| char const * pc = "12345678901234567890";
| std::istringstream iss(pc);
| iss >> d;
| if (d <= numeric_limits<int>::max()
| && d >= numeric_limits<int>::min())
| {
| a = static_cast<int>(d);
| cout << "Number is: " << a << endl;
| }
| else
| {
| cout << "Error: number " << iss.str();
| cout << " is out of range for int." << endl;
| }
| }
| catch(const std::exception &e)
| {
| cout << "Error: " << e.what() << endl;
| }
| return 0;
| }

It's not that much safer than the original :)

If I change the number to represent:
char const * pc = "1.234";

....the result is '1', clearly incorrect.

It also does not accommodate for trailing white space,
where as the 'strto*' functions do.

You can check it for this, as well as eof() condition,
which should do the trick:

template<typename T>
inline T ConvertTo( const char* const Source )
{
T Value( 0 );
std::istringstream Iss( Source );

if( !( Iss >> Value >> std::ws && Iss.eof() ) )
{
throw std::runtime_error(
"ERROR: Could not convert source string. " );
}

return Value;
}

int main()
{
std::string N( "123" );

try
{
std::cout << ConvertTo<int>( N.c_str() ) << std::endl;
}
catch( const std::runtime_error& e )
{
std::cerr << e.what() << std::endl;
}

return 0;
}

Cheers.
Chris Val
 
B

Bob Hairgrove

If I change the number to represent:
char const * pc = "1.234";

...the result is '1', clearly incorrect.

It also does not accommodate for trailing white space,
where as the 'strto*' functions do.

Yes, but the OP requested a way to convert a "NTBS of digits" ... not
a string containing random characters. Presumably the OP would have
checked the input first.
 
C

Chris \( Val \)

| On Sat, 23 Oct 2004 23:40:50 +1000, "Chris \( Val \)"
|
| >If I change the number to represent:
| > char const * pc = "1.234";
| >
| >...the result is '1', clearly incorrect.
| >
| >It also does not accommodate for trailing white space,
| >where as the 'strto*' functions do.
|
| Yes, but the OP requested a way to convert a "NTBS of digits"

Yes, that is correct.

| ... not a string containing random characters.

Are you saying that this is not an check worth performing ?

| Presumably the OP would have checked the input first.

Well, 'std::strto*' functions do that for you (discard
white space), as well as check for inappropriate chars,
so why shouldn't we model our 'std::stringstream' version
on the behaviour and principles of it's *robust* predecessors ?

Cheers.
Chris Val
 

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

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top