22

Stack Overflow has this question answered in many other languages, but not C. So I thought I'd ask, since I have the same issue.

How does one concatenate two integers in C?

Example:

x = 11;
y = 11;

I would like z as follows:

z = 1111;

Other examples attempt to do this with strings. What is a way to do this without strings?

I'm looking for an efficient way to do this in C because in my particular usage, this is going into a time critical part of code.

Thanks in Advance!

Claudiu
  • 224,032
  • 165
  • 485
  • 680
101010
  • 14,866
  • 30
  • 95
  • 172

10 Answers10

50
unsigned concatenate(unsigned x, unsigned y) {
    unsigned pow = 10;
    while(y >= pow)
        pow *= 10;
    return x * pow + y;        
}

Proof of compilation/correctness/speed

I avoid the log10 and pow functions, because I'm pretty sure they use floating point and are slowish, so this might be faster on your machine. Maybe. Profile.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
12
z = x * pow(10, log10(y)+1) + y;

Explanation:

First you get the number of digits of the variable that should come second:

int digits = log10(y)+1;  // will be 2 in your example

Then you "shift" the other variable by multiplying it with 10^digits.

int shifted = x * pow(10, digits);   // will be 1100 in your example

Finally you add the second variable:

z = shifted + y;   // 1111

Or in one line:

z = x * pow(10, (int)log10(y)+1) + y;
DrummerB
  • 39,814
  • 12
  • 105
  • 142
3

This may not be an optimal or fast solution but no one mentioned it and it's a simple one and could be useful.

You could use sprintf() and a strtol().

char str[100];
int i=32, j=45;
sprintf(str, "%d%d", i, j);
int result=strtol(str, NULL, 10);

You first write to a string the numbers one followed by the another with sprintf() (just like you would print to the stdout with printf()) and then convert the resultant string to the number with strtol().

strtol() returns a long which may be a value greater than what can be stored in an int, so you may want to check the resultant value first.

int result;
long rv=strtol(str, NULL, 10);
if(rv>INT_MAX || rv<INT_MIN || errno==ERANGE)
{
    perror("Something went wrong.");
}
else
{
    result=rv;
}

If the value returned by strtol() is not within the range of an int (ie, not between (including) INT_MIN and INT_MAX), error occurred. INT_MIN and INT_MAX are from limits.h.

If the value of in the string is too big to be represented in a long, errno will be set to ERANGE (from errno.h) because of the overflow.

Read about strtol() here.

Edit:

As the enlightening comment by chqrlie pointed out, negative numbers would cause trouble with this approach.

You could use this or a modification of this to get around that

char str[100], temp[50];
int i=-32, j=45, result;
sprintf(temp, "%+d", j);
sprintf(str, "%d%s", i, temp+1);
long rv=strtol(str, NULL, 10);

First print the second number to a character array temp along with its sign.

The + in %+d will cause the sign of the number to be printed.

Now print the first number and the second number to str but without the sign part of the second number. We skip the sign part of the second number by ignoring the first character in temp.

Finally the strtol() is done.

J...S
  • 5,079
  • 1
  • 20
  • 35
  • 1
    This is a good approach for dealing with potential overflow. Adding the corresponding code, setting and testing `errno` and comparing the result with `INT_MIN` and `INT_MAX` would be helpful. Negative values of `i` or `j` would also cause problems. – chqrlie Oct 02 '17 at 08:53
  • @chqrlie Thanks for taking the time to tell us that. I had not thought of the problem of negative numbers. Or the need to look at `INT_MIN`. – J...S Oct 22 '17 at 09:31
  • `if(rv>INT_MAX || rvLONG_MAX || rv – chux - Reinstate Monica Sep 27 '21 at 14:21
2
int myPow(int x, int p)
{
     if (p == 0) return 1;
     if (p == 1) return x;

     int tmp = myPow(x, p/2);
     if (p%2 == 0) return tmp * tmp;
     else return x * tmp * tmp;
}
int power = log10(y);
z = x*myPow(10,power+1)+y;

Here I shamelessly copied myPow from https://stackoverflow.com/a/1505791/1194873

Community
  • 1
  • 1
Tae-Sung Shin
  • 20,215
  • 33
  • 138
  • 240
2

Here is a variation of @Mooing Duck's answer that uses a lookup table for multiples of 10 (for platform's with slow integer multiply) It also returns unsigned long long to allow for larger values and uses unsigned long long in the lookup table to account for @chqrlie's comment about infinite loops. If the combined inputs can be guaranteed to not exceed unsigned, those could be changed.

static const unsigned long long pow10s[] = {
   10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000
};
unsigned long long concat(unsigned x, unsigned y) {
    const unsigned long long *p = pow10s;
    while (y >= *p) ++p;
    return *p * x +y;        
}
technosaurus
  • 7,676
  • 1
  • 30
  • 52
2

You can also use Macro to concatnate Strings ( Easy way )

#include<stdio.h>
#define change(a,b) a##b
int main()
 {
    int y;
    y=change(12,34);
    printf("%d",y);
    return 0;
 }

It has one Disadvantage. We can't pass arguments in this method

Jot Singh
  • 41
  • 4
1

here's another way to do it:

int concat(int x, int y) {
    int temp = y;
    while (y != 0) {
        x *= 10;
        y /= 10;
    }
    return x + temp;
}

who knows what performance you'll get. just try and see..

none
  • 11,793
  • 9
  • 51
  • 87
0

Maybe this will work:

int x=11,y=11,temp=0;
int z=x;
while(y>0)
{
    // take reciprocal of y into temp
    temp=(temp*10)+(y%10);       
    y=y/10;
}
while(temp>0)
{
    // take each number from last of temp and add to last of z
    z=(z*10)+(temp%10);      
    temp=temp/10;
}

code is lengthy , but is simple. correct me if there is any mistakes.

Jake1164
  • 12,291
  • 6
  • 47
  • 64
0

Improved variation on @Mooing Duck and @none answers.

Simply decimal shift x as needed.

unsigned concatenate2(unsigned x, unsigned y) {
  unsigned y_temp = y;
  do {  // do loop to insure at least one shift
    x *= 10;
    y_temp /= 10;
  } while (y_temp > 0);
  return x + y;  
}

Could use wider math to reduce overflow possibilites. @technosaurus

#include <inttypes.h>

uintmax_t concatenate2(unsigned x, unsigned y) {
  uintmax_t x_temp = x;
  unsigned y_temp = y;
  do {  // do loop to insure at least one shift
    x_temp *= 10;
    y_temp /= 10;
  } while (y_temp > 0);
  return x_temp + y;  
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
-3
#include<iostream>
using namespace std;

int main()
{
    int a=0,b=0,count=0,c=0,t=0;
    cout<<"enter 2 no"<<endl;
    cin>>a>>b;
    t=b;

    while(b!=0)
    {
        b=b/10;
        count++;
    }

    while(count!=0)
    {
        a=a*10;
        count--;
        c=a+t;
    }

    cout<<"concate no is:"<<c;
}
honk
  • 9,137
  • 11
  • 75
  • 83
  • 5
    The OP seeks for a solution in C. You provided a solution in C++, because you are using `cin` and `cout`. Moreover, you answer an old question which has already several well received answers. Why is your solution better so that it is worth posting? – honk Sep 21 '14 at 14:01