1

Working on a project where I get an input where its a comma delimited string like:

"255,10000000,42949672950254,12,22".

and then the numbers (no commas), would be split into 6 Long variables like

var1 = 255
var2 = 10000000
...

I wanted a function like this:

void extractIntegersFromString(String str, int& integer1, int& integer2, int& integer3, int& integer4, int& integer5, int& integer6, int& integer7) {
  int count = 0;
  String temp = "";

  for (int i = 0; i < str.length(); i++) {
    char c = str.charAt(i);

    if (c == ',') {
      if (count == 0)
        integer1 = String(temp).toInt();
      else if (count == 1)
        integer2 = String(temp).toInt();
      else if (count == 2)
        integer3 = String(temp).toInt();
      else if (count == 3)
        integer4 = String(temp).toInt();
      else if (count == 4)
        integer5 = String(temp).toInt();
      else if (count == 5)
        integer6 = String(temp).toInt();
      else if (count == 6)
        integer7 = String(temp).toInt();

      count++;
      temp = "";
    } else if (c >= '0' && c <= '9') {
      temp += c;
    }
  }

  // Store the last integer if the string doesn't end with a comma
  if (temp != "") {
    if (count == 0)
      integer1 = String(temp).toInt();
    else if (count == 1)
      integer2 = String(temp).toInt();
    else if (count == 2)
      integer3 = String(temp).toInt();
    else if (count == 3)
      integer4 = String(temp).toInt();
    else if (count == 4)
      integer5 = String(temp).toInt();
    else if (count == 5)
      integer6 = String(temp).toInt();
    else if (count == 6)
      integer7 = String(temp).toInt();
  }
}

This function makes it work through ints, but I need the larger size of a Long.

P.S. I've tried the atol() function (and similar others), but that didn't work...

0

2 Answers 2

2

First of all, it is worth noting that the third number in you example message (100000000000, i.e. 1011) is too large to fit in an unsigned long. On AVR-based Arduinos, and most non-64-bit platforms, an unsigned long is 32-bits wide and can only hold numbers up to 4294967295 (about 4.3×109). I do not know of any easy way to parse such a large number on AVR.

That being said, for parsing this kind of string into unsigned long numbers, I would recommend the strtoul() function. Compared to atol(), it has the benefit that it tells you where the number it read ended, so you know where to search for the next one: it saves you a call to strchr(). It also allows some error-checking, so you know whether the message does conform to the expected format.

Here is a tentative implementation:

/*
 * Parse up to `count` numeric values from `message`,
 * which must be in comma-separated-values format.
 *
 * Return the number of values successfully parsed.
 */
int parse_message(const char *message,
                  unsigned long *values, int count) {
    for (int i = 0; i < count; i++) {
        char *end;  // pointer to next non-digit
        values[i] = strtoul(message, &end, 10);
        if (end == message) return i;  // parsing failed
        if (*end == ',') end++;        // skip comma
        message = end;                 // move to the next field
    }
    return count;
}

And a small test sketch:

void setup() {
    Serial.begin(9600);

    unsigned long values[7];
    int count = parse_message("255,10000000,100000000000,0,255,12,22",
            values, 7);
    Serial.print(count);
    Serial.println(" numbers successfully parsed:");
    for (int i = 0; i < count; i++)
        Serial.println(values[i]);
}

void loop() {}
1
  • Thank you for your reply, I'll check it and I'll accept the answer for future reference!! :)
    – The Oracle
    Commented Jun 7, 2023 at 13:05
0

String.toInt actually returns a long. See the code:

long String::toInt(void) const
{
    if (buffer) return atol(buffer);
    return 0;
}

I've tried the atol() function (and similar others), but that didn't work

Please post your "try", don't just say that you did it. Maybe you did it incorrectly.


Re your entire technique: There is a function strtok that is specifically designed to break up a string into substrings at a delimiter. You could use that rather than re-inventing the wheel.

However that doesn't solve your specific problem of converting the substrings into a long.

3
  • Its a bit long; how would I include it here?
    – The Oracle
    Commented Jun 7, 2023 at 13:04
  • 1
    "Its a bit long; how would I include it here? " ... If someone asks for something in the comments, the answer (for just about any of the dozens of stackexchange web sites) is to edit the question and make it better.
    – st2000
    Commented Jun 7, 2023 at 17:37
  • Edit your question and show the half-a-dozen or so lines of code where you used the atol() function. Also show the results. "Didn't work" is to vague it could mean anything. Did it not compile? If it did compile what results did you get? Show the numbers. Don't say "it didn't work".
    – Nick Gammon
    Commented Jun 8, 2023 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.