Basic C++ question

Hello, i just started learning C++, this is why i got arduino, to learn it a little more. So my question would be, how do i this:

int a = 12;
int b = 42;

// If i do a + b, il get 54
// I need to get 1242, ie glue them together

Could anyone help me with it? :confused:

P.S: Im a PHP programmer, in PHP its really easy to do it it, you just do a = a . b; And you will get em glued.. Cant figure out how to do it in C++..

You could do:

int c = (a * 100) + b;

/is base-10 arithmetic not taught anymore?

:-?

That won't work unless you're only using two (or fixed digit numbers if you change 100 to 10 or 1000 etc.).

E.g.
a = 12
b = 189
(12 * 100) + 189 = 1389
12 . 189 = 12189

Easy in PHP because it's a variable type language. So the . operator uses each value as a string and then appends one to the other. If that new value is used in code as a number, it converts it.

Not sure how best to do this on an Arduino since I've not really tried programming it yet. You might have to write a function that uses itoa() on each parameter to produce string values. Appends one to the other and then atoi() to convert it back to a number. Not sure if you'd run out of range on the conversion back though.

Just been thinking about this a little more.

a = 12
b = 189
n = Floor ( Log10(b) + 1 ) = 3 (number of digits in the second number)

( a * (10^n) ) + b = c

So...

( 12 * (10^3) ) + 189 = 12189

a = 189
b = 1234
n = Floor( Log10(1234) + 1) = 4 (4 digits in b)
(a * (10^n)) + b = 1891234

Not sure off the top of my head how you do Floor and Log10 on the Arduino.

So basically what I'm saying is: Crosh was right (or righter than me anyway). :slight_smile:

@OP: Can you tell us exactly what it is you're trying to do?
Lots of ways of skinning this particular cat - BCD, decimal, hex.

I'd suggest itoa() and strcat() but please, correct me, if I'm wrong...

@Groove, well currently im tryng to get the Serial.read() into one variable, ie if i enter a number i want it all be in that variable.

But i would like to know how to do what i told too, since i was using it really much in PHP.

But i would like to know how to do what i told too, since i was using it really much in PHP.

I'm really struggling (not knowing PHP) to wonder why you would ever want to concatenate two decimal numbers (not digits) in this manner.

well currently im tryng to get the Serial.read() into one variable

I'm guessing you mean you're getting ASCII decimal digits one at a time, and you want to assemble them into a number.
I don't think comes up on the forum less than, ooh, about once a week.
I'm surprised it didn't show up in your searches.

Different ways:

  1. subtract '0' from each decimal digit, and add the result to a running total, suitably scaled by an appropriate power of ten.
  2. Put the digit character into a string, terminate the string, and call "atoi".
  3. as 2) but call scanf.
    and so on.

That won't work unless you're only using two (or fixed digit numbers if you change 100 to 10 or 1000 etc.).

You posted a very limited sample size; how am I suppose to extrapolate what you need to do from that? I made a logical assumption; I would have had to assume something regardless, given the level of details you provided.

E.g.
a = 12
b = 189
(12 * 100) + 189 = 1389
12 . 189 = 12189

If you checked "b" for its value (greater or less than 100, for instance), you could know whether to multiply "a" by 100 or by 1000. This algorithm could be expanded on (and generalized, given a bit of thought) to allow you to "concatenate" any number of numeric values.

Of course, if you wanted to concatenate "12" with the letter "b" (for "12b"), then you have to get into string concatenation; but you haven't said that's what you need...

Are you looking for a general string concatenation routine, or only concatenation of numeric values? You could, for instance, convert (cast) the values into strings, concatenate the values, then cast that value back to a numeric. Of course, both this method and the method I described previously above would run into variable sizing issues, so you could only create so large of a number.

If you don't need to use the concatenated number for further calculations, though, it could remain as a string.

Easy in PHP because it's a variable type language. So the . operator uses each value as a string and then appends one to the other. If that new value is used in code as a number, it converts it.

What you mean is PHP is a "non-typed" language; which isn't completely true - its similar to VB6 where all variables are, by default, these weird constructs called "variants" - as soon as you (or PHP) decides to cast that long string of numbers into an actual type for calculations, things probably get wonky (though to be honest, I've never tried this myself; I've never had the need to). Values might be truncated, or errors thrown - one of the two.

:slight_smile:

[edit]Oops - sorry, Eight; just saw your reply - if you keep working at what you are doing, though, you can come up with a generalized function/method to handle any number of values. It would probably be a recursive algorithm, but I don't think you would necessarily need special math functions (floor or log); I think you could get by with simple arithmetic, and maybe some decision tree logic. :)[/edit]

Hi Crosh,

I was just pointing out to the OP that coding in a multiplier of 100 wouldn't work in all cases. I wasn't 100% sure what he wanted either so was trying to suggest something a bit more general - hence my use of floor and log10 which might be not necessary (as you said) :slight_smile:

What you mean is PHP is a "non-typed" language

I was probably looking for that term, or "dynamic typing" perhaps. Not sure where in my sleepy head "variable type" came from. :smiley:

I'm not much of a fan of variants either as it happens. You know where you stand with strongly typed variables and having to explicitly cast from one type to another.

You know where you stand with strongly typed variables and having to explicitly cast from one type to another.

That you do. Unless the types are defined using conditionally compiled typedef statements spread across two dozen include files.

Then, you just want to throw up your hands and go back to a weakly typed system and let it figure out how to convert the data to the required type.

How about this?

char concatenated[ 20 ];
sprintf( concatenated, "%d%d", a, b );

The result will be a string of chars in 'concatenated'. If you need it back as in int, do:

char concatenated[ 20 ];
int newInt = int( sprintf( concatenated, "%d%d", a, b ) );

You'll have to be careful about integer overflow in the second example.

I think snprintf() is really what you are after...

Lets consider types first, you know that the largest base-10 number you will ever see in a 8-bit number is 3 digits, so to concatenate 2 8-bit numbers you will need 7 bytes of buffer. With 16 bits, the largest base-10 number will be 5 digits, meaning you need 11 bytes. Remember you need to provide room for the terminating null '\0'.

const int bufsz(11);
char buf[bufsz];
int a(1234), b(567);
snprintf(buf, bufsz, "%i%i", a, b);

Now buf contains { '1', '2', '3', '4', '5', '6', '7', '\0', X, X, X }, where X is undefined, but who cares, it all fit...

@Deeg
Before offering this advice:

If you need it back as in int, do:

char concatenated[ 20 ];
int newInt = int( sprintf( concatenated, "%d%d", a, b ) );

you might want to look at WHAT sprintf returns.

Return Value
On success, the total number of characters written is returned. This count does not include the additional null-character automatically appended at the end of the string.
On failure, a negative number is returned.

So, if a = 123, and b = 456, sprintf returns the integer value 6, which does not need to be converted to an int (which is what int() does). So, newInt would contain 6, which is nowhere near 123,456.

You're right, I had a brain fart. The correct code is:

char concatenated[ 20 ];
sprintf( concatenated, "%d%d", a, b );
int newInt = int( concatenated );

Cra pointed out that snprintf would be better than sprintf.

I don't think that that works either. You can't cast a string to anything and expect it to do data conversion, because a string in C/C++ is a pointer to chars, rather than a real data type that casting knows how to do things with ("string" C++ packages may have the capability.)
You can use "atoi(concatenated)"

You can use "atoi(concatenated)"

After concatenating two int's, there is a good likelihood that the result is no longer an int. I'd be more inclined to use atol (ascii to long).

But, yeah, this is the way to convert strings to integers.

Oy...this is what happens when you don't test. The doc says "int(...)" can handle any data type but it doesn't handle 'char *' (at least not the way I'd expect it to). Looks like it's just using the pointer value. I was assuming that int(...) would basically call atoi().

So yeah, just ignore what I wrote. Except for the overflow part--I think I was right about the possibility of overflow. :wink: