string or character to integer problem

J

johnny

Can anyone tell me what is wrong with the following code fragment?

char a = x[index];
char b = y[index];
int result = strtol(&a, NULL, 10) + strtol(&b, NULL, 10);

I got the same result using result=atoi(&a)+atoi(&b);

cout << a << '\t' << b << endl; shows the values of a and b to be correct.

cout << atoi(&a) (or strtol(&a, NULL, 10)) is correct but atoi(&b) and
strtol(&b, NULL, 10) are incorrect.

This project is suppose to take integers of "unlimited" size and add them.

Mandrake Linux 10, gcc-c++-3.3.2-6mdk, kernel 2.6.3-15mdk
 
D

David Harmon

On Sat, 17 Jul 2004 23:30:07 GMT in comp.lang.c++, (e-mail address removed)
wrote,
Can anyone tell me what is wrong with the following code fragment?

char a = x[index];
char b = y[index];
int result = strtol(&a, NULL, 10) + strtol(&b, NULL, 10);

strtol does not take a pointer to a single char. Very few things do;
when you see (char *) you can usually assume that it is a pointer to an
array of chars, and most often a zero-terminated string.

Using strtol to convert a single char is silly anyway, just subtract
'\0'.
 
J

johnny

David said:
On Sat, 17 Jul 2004 23:30:07 GMT in comp.lang.c++, (e-mail address removed)
wrote,
Can anyone tell me what is wrong with the following code fragment?

char a = x[index];
char b = y[index];
int result = strtol(&a, NULL, 10) + strtol(&b, NULL, 10);

strtol does not take a pointer to a single char. Very few things do;
when you see (char *) you can usually assume that it is a pointer to an
array of chars, and most often a zero-terminated string.

Using strtol to convert a single char is silly anyway, just subtract
'\0'.

I'm not sure of what you're trying to say about the subtraction.

Anyway, I normally use atoi() to convert a character (or string) to an
integer. There's probably a better way to do what I'm trying to do but this
is a first draft anyway. I need to be able to add 2 large integers that are
larger than can be stored in an unsigned long.

As it turns out, on my system, any integer type uses 4 bytes (according to
the return from sizeof()). Anyway, I'm entering the values as strings and
storing them in a vector.

Besides, I still need to know why the first call to strtol() returns the
correct value while the second call to strtol() doesn't.
 
D

David Harmon

On Sun, 18 Jul 2004 01:58:27 GMT in comp.lang.c++, (e-mail address removed)
wrote,
I'm not sure of what you're trying to say about the subtraction.

I made a mistake in that part anyway. What I mean is that if a is char
in the range '0' through '9', then a-'0' is the corresponding value in
the range 0 through 9.
Anyway, I normally use atoi() to convert a character (or string) to an
integer.

Again, atoi(), strtol(), etc are only for converting zero-terminated c
style array strings, never single characters. If it works for single
char variables it is only by good or bad luck.
Besides, I still need to know why the first call to strtol() returns the
correct value while the second call to strtol() doesn't.

It depends on what happens by chance to follow the variable in memory.
Both the first and thee second are still equally wrong.
 
K

Kai-Uwe Bux

David said:
On Sat, 17 Jul 2004 23:30:07 GMT in comp.lang.c++, (e-mail address removed)
wrote,
Can anyone tell me what is wrong with the following code fragment?

char a = x[index];
char b = y[index];
int result = strtol(&a, NULL, 10) + strtol(&b, NULL, 10);

strtol does not take a pointer to a single char. Very few things do;
when you see (char *) you can usually assume that it is a pointer to an
array of chars, and most often a zero-terminated string.

Using strtol to convert a single char is silly anyway, just subtract
'\0'.

I'm not sure of what you're trying to say about the subtraction.

To convert a char c to a digit, you can use:

digit = c - '0';
Anyway, I normally use atoi() to convert a character (or string) to an
integer. There's probably a better way to do what I'm trying to do but
this is a first draft anyway. I need to be able to add 2 large integers
that are larger than can be stored in an unsigned long.

As it turns out, on my system, any integer type uses 4 bytes (according to
the return from sizeof()). Anyway, I'm entering the values as strings and
storing them in a vector.

Besides, I still need to know why the first call to strtol() returns the
correct value while the second call to strtol() doesn't.

You pass &b to strtol, which expects a char*. Since &b is compatible with
char* this will compile. However, strtol thinks of its first argument as
pointing to the *beginning* of a string. So instead of just converting one
digit, you will effectively convert the whole trail of the array y starting
at index. This is what strtol does, but it is not what you want. (And this
was already hinted at in the first reply you quoted.)


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

I need to correct myself:

Kai-Uwe Bux said:
char a = x[index];
char b = y[index];
int result = strtol(&a, NULL, 10) + strtol(&b, NULL, 10);
Besides, I still need to know why the first call to strtol() returns the
correct value while the second call to strtol() doesn't.

You pass &b to strtol, which expects a char*. Since &b is compatible with
char* this will compile. However, strtol thinks of its first argument as
pointing to the *beginning* of a string. So instead of just converting one
digit, you will effectively convert the whole trail of the array y
starting at index.

This is not what happens. Since the variable b lies at some unpredictable
location in memory, it is not the trail of the array y that follows but
some random stuff that may or may not consist of digits. This is what
strtol will try to convert. In fact, the programm could crash as well if it
does not own the memory following &b.
 
J

johnny

Thanks. Yep, (a - '0') is a better way to go.

Kai-Uwe Bux said:
David said:
On Sat, 17 Jul 2004 23:30:07 GMT in comp.lang.c++, (e-mail address removed)
wrote,
Can anyone tell me what is wrong with the following code fragment?

char a = x[index];
char b = y[index];
int result = strtol(&a, NULL, 10) + strtol(&b, NULL, 10);

strtol does not take a pointer to a single char. Very few things do;
when you see (char *) you can usually assume that it is a pointer to an
array of chars, and most often a zero-terminated string.

Using strtol to convert a single char is silly anyway, just subtract
'\0'.

I'm not sure of what you're trying to say about the subtraction.

To convert a char c to a digit, you can use:

digit = c - '0';
Anyway, I normally use atoi() to convert a character (or string) to an
integer. There's probably a better way to do what I'm trying to do but
this is a first draft anyway. I need to be able to add 2 large integers
that are larger than can be stored in an unsigned long.

As it turns out, on my system, any integer type uses 4 bytes (according
to the return from sizeof()). Anyway, I'm entering the values as strings
and storing them in a vector.

Besides, I still need to know why the first call to strtol() returns the
correct value while the second call to strtol() doesn't.

You pass &b to strtol, which expects a char*. Since &b is compatible with
char* this will compile. However, strtol thinks of its first argument as
pointing to the *beginning* of a string. So instead of just converting one
digit, you will effectively convert the whole trail of the array y
starting at index. This is what strtol does, but it is not what you want.
(And this was already hinted at in the first reply you quoted.)


Best

Kai-Uwe Bux
 
J

johnny

Thanks. That is a better way to go. I don't know why I didn't think of that
earlier since it was something I once learned in my C class many years ago.
I'll get back up to speed again (I hope).
 
J

JKop

Kai-Uwe Bux posted:

To convert a char c to a digit, you can use:

digit = c - '0';


But I don't think that this is portable - for example, in a
certain codepage, there's a gap between the letter 'i' and
'j', ie. they're no sequential.


-JKop
 
S

Serge Paccalin

Le dimanche 18 juillet 2004 à 11:26:31, JKop a écrit dans
comp.lang.c++ :
Kai-Uwe Bux posted:


But I don't think that this is portable - for example, in a
certain codepage, there's a gap between the letter 'i' and
'j', ie. they're no sequential.

Letters are not guaranteed to be sequential, but digits are. So the
proposed conversion is portable.

--
___________ 2004-07-18 14:11:04
_/ _ \_`_`_`_) Serge PACCALIN -- sp ad mailclub.net
\ \_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
 
D

David Rubin

JKop said:
Kai-Uwe Bux posted:




But I don't think that this is portable - for example, in a
certain codepage, there's a gap between the letter 'i' and
'j', ie. they're no sequential.

IIRC, this always works for digits; the standard guarantees that
numerals are consecutive from '0' to '9'. /david
 

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

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,477
Latest member
ColumbusMa

Latest Threads

Top