2

Once again I have the wrong data type. This is an arduino project.

I have a char array. The last 9 characters are rgb, I get them as triplets. So 000255000.

I need to pass those to a function but as integers, like 0, 255, 0. I'm ok if 000 turns into 0, but I need 045 to turn into 45.

I've tried to cast them, like:

blue = (int)message[11];
blue += (int)message[12];
blue += (int)message[13];

That did not work. I could however cast them to strings,which I did, then I tried: Yes, I know this was not a great idea, but it was worth a shot.

char tempBlue[4];
blue.toCharArray(tempGreen, sizeof(tempGreen));
iBlue = atoi(tempGreen);

That also did not work.

I'm lost as to how to do this. I have no idea how ( if you can ) concatenate integers or I would have tried that.

EDIT------

Am I asking the wrong question. Should I be doing this the reverse way around. Concatenate first then to integer? I have them as characters to begin with.

TheEditor
  • 486
  • 1
  • 4
  • 18
  • You can "concatenate" two integers quite simply if the second one is less than 10: just compute 10 * A + B. – Lee Daniel Crocker Jun 10 '15 at 21:21
  • `blue.toCharArray(tempGreen, sizeof(tempGreen));` - are you sure this is C? – user4520 Jun 10 '15 at 21:28
  • @LeeDanielCrocker - Well, I just saw your post. It jogged my brain. I know that each digit is only 0-5. So int combined = ((100 * first) + (10 * second) + third); was all I needed. I was making it WAYYYY to complicated. Man, I feel dumb. – TheEditor Jun 10 '15 at 22:36
  • @TheEditor 1) Minor: "each digit is only 0-5" - the last two digits could be `0-9`. 2) Yes, we all over-thought this: `blue = (message[11]-'0')*100 + (message[12]-'0')*10 + message[13]-'0';` was all that is needed. – chux - Reinstate Monica Jun 10 '15 at 23:10
  • @chux Yep pretty much that. I just have to laugh. Some simple math and all is well. – TheEditor Jun 11 '15 at 00:27

5 Answers5

1

To convert each character to its respective int do the following

int first = message[11] - '0';
int second= message[12] - '0';
int third = message[13] - '0';

To see why this works, you can check here: Why does subtracting '0' in C result in the number that the char is representing?

To concatenate ints, you could use this function

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

I did not write this function, it was written by @TBohne originally here

Community
  • 1
  • 1
Greg Hilston
  • 2,397
  • 2
  • 24
  • 35
  • Ok, I'll try that. Then how to I concatenate that? – TheEditor Jun 10 '15 at 20:52
  • @TheEditor See my original answer, I edited it to answer your follow up question – Greg Hilston Jun 10 '15 at 20:57
  • Ok that converts them perfectly, and I learned something. As for the concatenation, do I even have to do that? I'll be using them like this: colorWipe(strip.Color(255, 0, 0), 50); Is there a better way of getting say the 255 in there from individual integers other than concatenating? Though building each triplet would let me get rid of leading zeros along the way. What is the best way here? – TheEditor Jun 10 '15 at 22:12
  • 1
    Ignore that I figured it out. I replied to an earlier post that int combined = ((100 * first) + (10 * second) + third); was all I needed since the numbers were only ever going to be 0-255. Making it harder than I needed to. – TheEditor Jun 10 '15 at 22:37
  • With large values of `y`, `while(y >= pow) pow *= 10;` is an infinite loop. – chux - Reinstate Monica Jun 10 '15 at 23:01
1

I'd go with:

char *partMessage = (char*)malloc(4);
partMessage[3] = '\0';
strncpy(partMessage, message + 11, 3);
result = (int)strtol(partMessage, NULL, 10);
free(partMessage);
Alexandre Severino
  • 1,563
  • 1
  • 16
  • 38
0

you could try something like this

#include <stdio.h>

int main()
{
  // example
  char message[] = { "000255000" };
  int r=0, g=0, b=0;

  // make sure right number of values have been read
  if ( sscanf(message, "%03d%03d%03d", &r, &g, &b ) == 3 )
  {
    printf( "R:%d, G:%d, B:%d\n", r,g,b );
  }
  else
  {
    fprintf(stderr, "failed to parse\n");
  }
}

sscanf will skip any white space so even a string like message[] = " 000 255 000 "; will work.

AndersK
  • 35,813
  • 6
  • 60
  • 86
0

Just do the conversion manually:

int convert_digits(char *cp, int count) {
    int result = 0;
    for (int i = 0; i < count; i += 1) {
        result *= 10;
        result += (cp[i] - '0');
    }
    return result;
}

char *input = "000045255";

int main(int ac, char *av[]) {
    printf("r=%d g=%d, b=%d\n",
        convert_digits(cp, 3),
        convert_digits(cp+3, 3),
        convert_digits(cp+6, 3));
}
Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55
0

Convert string to a number and then numerically peal off 3 digits at a time.

const char *s = "000255000";
char *endptr;
unsigned long num = strtoul(s, &endptr, 10);

// add error checking on errno, num, endptr) here if desired.

blue = num%1000;
num /= 1000;
green = num%1000;
num /= 1000;
red = num%1000;

// Could add check to insure r,g,b <= 255.
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256