4

This is the sample code of my program, in which i've to add two string type integer (ex: "23568" and "23674"). So, i was trying with single char addition.

char first ='2';
char second ='1';

i was trying like this..

i=((int)first)+((int)second);
printf("%d",i);

and i'm getting output 99, because, it's adding the ASCII value of both. Anyone please suggest me, what should be the approach to add the char type number in C.

Ravi
  • 30,829
  • 42
  • 119
  • 173
  • What about `char *first = "235668";` `char second="23674";` ... `printf("%d\n", atoi(first)+atoi(second));`? – yeyo Nov 12 '12 at 13:32
  • will it work, when characters length will be 1000 ?? – Ravi Nov 12 '12 at 13:33
  • mmm I think no, even on a 64bit computer, 100 digits is too much. http://gmplib.org/ – yeyo Nov 12 '12 at 13:37
  • so, in that case it won't be helpful for me. Because, in the original question, the maximum limit was given upto 1000 characters. – Ravi Nov 12 '12 at 13:39
  • check the link about the GNU gmplib "arithmetic without limitations". Again http://gmplib.org/ – yeyo Nov 12 '12 at 13:40
  • You should update your question, people is providing another kind of ans. Maybe someone has experience with the gmplib – yeyo Nov 12 '12 at 13:43
  • be careful, you can't have a 100digits integer, unless you have hell of a good processor, so, you won't be able to do operations like, addition, subtraction. You could iterate over the whole string, char by char ..., but that will be quite inefficient and IMO a little hard to do and maintain. – yeyo Nov 12 '12 at 13:54
  • @Kira, Never use `atoi`! Use `strtol` instead and specify base 10. `atoi` thinks 012 is 10, because it treats numbers with a leading zero as octal. – Ben Nov 12 '12 at 15:43
  • @Ben **no**, the man page explicitly says: _The behavior is the same as `strtol(nptr, (char **) NULL, 10);` except that atoi() does not detect errors._ Also I tried the case you describe and it worked as expected. Which compiler do you use? – yeyo Nov 12 '12 at 15:57
  • @Kira, Having googled it I find that you are correct inasmuch as the behaviour was changed with ANSI standard C in 1990. However this problem bit a nationwide application I supported in 2005, which didn't even begin until several years after the standard was adopted. (I diagnosed the bug based on my memory of K&R, I didn't introduce it). Standards take a long time to adopt. Even so, `atoi` is deprecated and should not be used for that reason. – Ben Nov 12 '12 at 16:30
  • @Ben, Thank you for sharing your experience, I'll keep away from `atoi()`. – yeyo Nov 12 '12 at 16:53

9 Answers9

9

Since your example has two single chars being added together, you can be confident knowing two things

  1. The total will never be more than 18.
  2. You can avoid any conversions via library calls entirely. The standard requires that '0' through '9' be sequential (in fact it is the only character sequence that is mandated by the standard).

Therefore;

char a = '2';
char b = '3';

int i = (int)(a-'0') + (int)(b-'0');

will always work. Even in EBCDIC (and if you don't know what that is, consider yourself lucky).

If your intention is to actually add two numbers of multiple digits each currently in string form ("12345", "54321") then strtol() is your best alternative.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • Downvoted because what if there is a non-digit character there? What about a space? A decimal point? – Ben Nov 12 '12 at 15:54
  • 1
    @Ben down vote wrong because the answer is for a specific question and not for general question. he is not intended to answer to a question not asked so I upvote – MOHAMED Nov 12 '12 at 16:44
  • @MohamedKALLEL, suit yourself. ***always work*** is just not true though, is it? Also it is a bad answer because it encourages avoiding "any conversions via library calls" in favour of hand coding something worse. All conversions should be via library calls, because if you hand code everything you will make more mistakes = more bugs. – Ben Nov 12 '12 at 17:18
  • 1
    If you can demonstrate a way, real, ethereal, or otherwise, that the variables `a` and/or `b` in this answer, *will* change between between the moment `b` is assigned '3' and the value of `i` is computed, I will remove not only "always work", I'll remove the answer outright. The OP asked a specific question. If the specific answer provided does not suit the question *you* read between the lines of theirs, so be it. That is why more than one person can answer the question (and plenty did). But given the above three lines of code, *always work* is not only correct, it is *provably* so. – WhozCraig Nov 12 '12 at 18:35
  • 1
    WhozCraig is correct since the numbers '0' to '9' are _guaranteed_ by the standard 5.2.1 "In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous." These are the only symbols that the standard guarantees are adjacent in the symbol table. – Lundin Nov 12 '12 at 20:01
  • However, the cast to int is completely superfluous, as the expression will already be `int`, since character literals are of type int in C (unlike C++). – Lundin Nov 12 '12 at 20:04
  • @WhozCraig, to your challenge, if it is only supposed to work for `'2'` and `'3'` then you could just return a constant value. You need something which also behaves correctly for `'T'`, `'D'`, `'W'`, `'T'` and `'F' (http://thedailywtf.com/). Yours does not. – Ben Nov 12 '12 at 20:43
  • 1
    If you're interpretation of the OP's request to calculate the integer result of single digit-character addition requires handling the undefined behavior of something not asked, so be it. If you prefer set-notation or a regular expression to qualify domain-restriction (not asked by the OP), so also be it. Again, that is why SO allows, and encourages, multiple answers. By your conjecture a 3-param-minimum would be necessary for *all* two-param-to-result calculations; one for each param, one for the result, and returning a boolean condition of success or failure. I can live with that if you can. – WhozCraig Nov 12 '12 at 21:18
  • 1
    @Lundin sry, the cast was my C++ side bleeding over. Happens from time to time. At least being superfluous on this side (in this case) has no oddity of side-effect; Failing to be explicit on the other side (C++) can have disastrous results, as we've all dealt with at least a time or two. – WhozCraig Nov 12 '12 at 21:22
5
i=(first-'0')+(second-'0');

No need for casting char to int.

MOHAMED
  • 41,599
  • 58
  • 163
  • 268
  • oooh good answer :), but I think he needs a little help converting from one type to another (I think) – yeyo Nov 12 '12 at 13:26
  • 2
    The casts are entirely unnecessary. `'0'` is already an `int`, and even if it weren't, the integer promotions are applied to the arguments of `-`, so the arithmetic is done at type `int` anyway. – Daniel Fischer Nov 12 '12 at 13:59
  • indeed, there is no need for type cast, C++ people tend to do this. – yeyo Nov 12 '12 at 14:03
  • question updated for the casting. could you please provide some links that proves no need to cast char to int – MOHAMED Nov 12 '12 at 16:46
  • 1
    [The C standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) 6.3.1.1/2: `"If an int can represent all values of the original type... the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.` The integer promotions are in turn part of balancing ("the usual arithmetic conversions" 6.3.1.8). – Lundin Nov 12 '12 at 19:53
  • Daniel, why is '0' already an int, isn't it in single quotes? – committedandroider Oct 03 '14 at 20:06
1

if you want to add the number reprensations of the characters, I would use "(first - '0') + (second - '0');"

Peter Miehle
  • 5,984
  • 2
  • 38
  • 55
1

The question seemed interesting, I though it would be easier than it is, adding "String numbers" is a little bit tricky (even more with the ugly approach I used).

This code will add two strings of any length, they doesn't need to be of the same length as the adding begins from the back. Your provide both strings, a buffer of enough length and you ensure the strings only contains digits:

#include <stdio.h>
#include <string.h>

char * add_string_numbers(char * first, char * second, char * dest, int dest_len)
{
    char * res = dest + dest_len - 1;
    *res = 0;

    if ( ! *first && ! *second )
    {
        puts("Those numbers are less than nothing");
        return 0;
    }

    int first_len = strlen(first);
    int second_len = strlen(second);

    if ( ((first_len+2) > dest_len) || ((second_len+2) > dest_len) )
    {
        puts("Possibly not enough space on destination buffer");
        return 0;
    }

    char *first_back = first+first_len;
    char *second_back = second+second_len;

    char sum;
    char carry = 0;

    while ( (first_back > first) || (second_back > second) )
    {
        sum = ((first_back  > first)  ? *(--first_back) : '0')
            + ((second_back > second) ? *(--second_back) : '0')
            + carry - '0';

        carry = sum > '9';
        if ( carry )
        {
            sum -= 10;
        }

        if ( sum > '9' )
        {
            sum = '0';
            carry = 1;
        }

        *(--res) = sum;
    }

    if ( carry )
    {
        *(--res) = '1';
    }

    return res;
}

int main(int argc, char** argv)
{
    char * a =              "555555555555555555555555555555555555555555555555555555555555555";
    char * b = "9999999999999666666666666666666666666666666666666666666666666666666666666666";
    char r[100] = {0};

    char * res = add_string_numbers(a,b,r,sizeof(r));

    printf("%s + %s = %s", a, b, res);

    return (0);
}
aaronps
  • 324
  • 1
  • 6
0

Well... you are already adding char types, as you noted that's 4910 and 5010 which should give you 9910

If you're asking how to add the reperserented value of two characters i.e. '1' + '2' == 3 you can subtract the base '0':

printf("%d",('2'-'0') + ('1'-'0')); 

This gives 3 as an int because:

'0' = ASCII 48<sub>10</sub>
'1' = ASCII 49<sub>10</sub>
'2' = ASCII 50<sub>10</sub>

So you're doing:

printf("%d",(50-48) + (49-48));

If you want to do a longer number, you can use atoi(), but you have to use strings at that point:

int * first = "123";
int * second = "100";
printf("%d", atoi(first) + atoi(second));

>> 223
Mike
  • 47,263
  • 29
  • 113
  • 177
  • Never use `atoi`! Use `strtol` instead and specify base 10. `atoi` thinks 012 is 10, because it treats numbers with a leading zero as octal. – Ben Nov 12 '12 at 15:43
  • @Ben - `atoi()` is equivalent to `strtol(nptr, (char **) NULL, 10)` (except for the error checking). That's mentioned a number of places including the man for `atoi`. Passing `char * num = "012";` to `atoi()` using gcc 4.6.2 yeilds the same as using `strtol`. – Mike Nov 12 '12 at 15:57
  • Having googled it I find that you are correct inasmuch as the behaviour was changed with ANSI standard C in 1990. However this problem bit a nationwide application I supported in 2005, which didn't even begin until many years after the standard was adopted. (I diagnosed the bug based on my memory of K&R, I didn't introduce it). Standards take a long time to adopt. Even so, `atoi` is deprecated so I am still downvoting. – Ben Nov 12 '12 at 16:28
  • @Ben - `atoi is deprecated` - Based on your comment, do you have newer information than what is in this question here? http://stackoverflow.com/questions/2892951/list-of-deprecated-c-functions – Mike Nov 12 '12 at 16:32
  • @Ben - Just to be very clear here... I just checked `/usr/include/stdlib.h` ISO C99 7.20 (2011 copyright) and it doesn't mention it's deprecated. Normally they add some comments and `__THROW __attribute_deprecated__;` when it's no good anymore. So if you have something newer that shows it's no good I'd be happy to update my post. – Mike Nov 12 '12 at 16:53
  • It's documented as deprecated by BSD, Apple, by the CERT secure C coding standards and by a bunch of different vendors. See for example https://www.securecoding.cert.org/confluence/display/seccode/INT06-C.+Use+strtol%28%29+or+a+related+function+to+convert+a+string+token+to+an+integer and https://www.securecoding.cert.org/confluence/display/seccode/INT05-C.+Do+not+use+input+functions+to+convert+character+data+if+they+cannot+handle+all+possible+inputs on the CERT standards. – Ben Nov 12 '12 at 17:13
0

In fact, you don't need to even type cast the chars for doing this with a single char:

 #include <stdlib.h>
 #include <stdio.h>
 int main(int argc, char* argv[]) {
     char f1 = '9';
     char f2 = '7';
     int v = (f1 - '0') - (f2 - '0');
     printf("%d\n", v);

     return 0;
 }

Will print 2

But beware, it won't work for hexadecimal chars

higuaro
  • 15,730
  • 4
  • 36
  • 43
0

This will add the corresponding characters of any two given number strings using the ASCII codes.

  • Given two number strings 'a' and 'b', we can compute the sum of a and b using their ASCII values without type casting or trying to convert them to int data type before addition.

Let

char *a = "13784", *b = "94325";
int max_len, carry = 0, i, j; /*( Note: max_len is the length of the longest string)*/
char sum, *result;

Adding corresponding digits in a and b.

    sum = a[i] + (b[i] - 48) + carry; /*(Because 0 starts from 48 in ASCII) */

    if (sum >= 57)
        result[max_len - j] = sum - 10;
        carry = 1;
    else
        result[max_len - j] = sum;
        carry = 0;



 /* where (0 < i <= max_len and 0 <= j <= max_len) */

NOTE: The above solution only takes account of single character addition starting from the right and moving leftward.

Austin
  • 1
  • 4
-1

if you want to scan number by number, simple atoi function will do it

  • `atoi` is deprecated. Use `strotl` and specify base 10. – Ben Nov 12 '12 at 16:29
  • @Ben Actually, atoi is still valid, though `strtol` is indeed to prefer. The standard actually defines atoi to be equal to `(int)strtol(nptr, (char **)NULL, 10)`. – Lundin Nov 12 '12 at 20:08
  • I'm basically a firmware developer, so, in case I need suche a conversion, I usually pick up the simplest and fittest solution, hoping to save code rom. I'll consider strtol when developing PC apps. Thank you guys! – graziano governatori Nov 15 '12 at 14:10
-2

you can use atoi() function

#include <stdio.h>
#include <stdlib.h>
void main(){
    char f[] = {"1"};
    char s[] = {"2"};
    int i, k;
    i = atoi(f);
    k = atoi(s);
    printf("%d", i + k);
    getchar();
}

Hope I answered you question

Willy Pt
  • 1,795
  • 12
  • 20
  • strtol is better, since it has well-defined error handling. atoi will just halt & catch fire if it gets fed invalid input. – Lundin Nov 12 '12 at 15:34
  • `atoi` is deprecated. Use `strotl` and specify base 10. – Ben Nov 12 '12 at 16:29