How to convert a string to a number

by Len17 on Sat Dec 31, 2011 10:37 pm

Here's a task that Arduino programming newbies often struggle with: Take a number represented as a string of ASCII digit characters (e.g. "12345") and convert it to an integer variable.

If the string is variable length and null terminated (the usual format for strings in C and Arduino), there's a built-in function to do it. Here's a simple sketch to demonstrate:

Code: Select all | TOGGLE FULL SIZE
#include <stdlib.h> // for the atol() function

#define numBufSize 11
char numStr[numBufSize] = "3141592654"; // just as an example

void setup()
{
  Serial.begin(115200);
 
  // Convert decimal string in numStr to an unsigned integer in num.
  // The string must be null-terminated!
  unsigned long num;
  num = atol(numStr);
 
  Serial.println(num);
}

void loop()
{
}


If the string is in a fixed length buffer with no null terminator character, it's a bit more complicated:

Code: Select all | TOGGLE FULL SIZE
#define numBufSize 11
char numStr[numBufSize] = { '0','3','1','4','1','5','9','2','6','5','4' }; // just as an example

void setup()
{
  Serial.begin(115200);
 
  // Convert decimal string in numStr to an unsigned integer in num.
  // The string is in a fixed size buffer.
  // There is no checking for invalid digit characters or number too large.
  unsigned long num = 0;
  for (int i = 0; i < numBufSize; i++) {
    num = num * 10 + (numStr[i] - '0');
  }
 
  Serial.println(num);
}

void loop()
{
}
User avatar
Len17
 
Posts: 393
Joined: Sat Mar 14, 2009 6:20 pm

Re: How to convert a string to a number

by miax on Sat Dec 31, 2011 10:42 pm

Thanks for posting this Len! :)

I had seen atol() a few times but never tried it, I can definitely make use of this!

One other challenge I have to overcome is converting a 16-character string that holds a uint32_t (unsigned long), will atol() work for really big numbers? (like what we get out of millis()?

Happy new year! :)

Kris
Kristopher Kortright
Father, Husband, Horseman, Maker, Writer, Internet Technologist and Inventor of Strange of Useful Things
Supporter of the Open Source Hardware movement
User avatar
miax
 
Posts: 134
Joined: Tue Apr 05, 2011 10:41 am

Re: How to convert a string to a number

by miax on Sat Dec 31, 2011 10:45 pm

Here is the crazy function I'm using now to convert a char[16] to unsigned long, and this one only actually works for 10 characters (not 16).

Code: Select all | TOGGLE FULL SIZE
// Convert an entire string of numbers (max 9) from char to unsigned int.
void XNPconvertSerialToNum()
{
  serialNumber = 0;
  // First flip the string around so we start from the back.
  sprintf(buffer1, "");
  bufferlen = strlen(serialnum);
  for(x = 0; x < bufferlen; x++) {
    if(x == 0) g = bufferlen - 1;
    if(x == 1) g = bufferlen - 2;
    if(x == 2) g = bufferlen - 3;
    if(x == 3) g = bufferlen - 4;
    if(x == 4) g = bufferlen - 5;
    if(x == 5) g = bufferlen - 6;
    if(x == 6) g = bufferlen - 7;
    if(x == 7) g = bufferlen - 8;
    if(x == 8) g = bufferlen - 9;
    if(x == 9) g = bufferlen - 0;
    sprintf(buffer2, "%c", serialnum[g]);
    strcat(buffer1, buffer2);
  }
  bufferlen = strlen(buffer1);
  if(bufferlen > SERIAL_LENGTHS) {
    bufferlen = SERIAL_LENGTHS;
  }
  // Now parse the individual numbers out.
  sprintf(buffer3, "");
  for(x = 0; x < bufferlen; x++) {
    sprintf(buffer2, "%c", buffer1[x]);
    g = XNPconvertLetterToNumber();
    if(x == 0) {
      serialNumber += g;
    } else if(x == 1) {
      if(g > 0) {
        serialNumber += (g * 10);
      }
    } else if(x == 2) {
      if(g > 0) {
        serialNumber += (g * 100);
      }
    } else if(x == 3) {
      if(g > 0) {
        serialNumber += (g * 1000);
      }
    } else if(x == 4) {
      if(g > 0) {
        serialNumber += (g * 10000);
      }
    } else if(x == 5) {
      if(g > 0) {
        serialNumber += (g * 100000);
      }
    } else if(x == 6) {
      if(g > 0) {
        serialNumber += (g * 1000000);
      }
    } else if(x == 7) {
      if(g > 0) {
        serialNumber += (g * 10000000);
      }
    } else if(x == 8) {
      if(g > 0) {
        serialNumber += (g * 100000000);
      }
    } else if(x == 9) {
      if(g > 0) {
        serialNumber += (g * 1000000000);
      }
    }
  }
}
// This converts a String with a single number [0-9] and returns the numeric integer.xyzzy
int XNPconvertLetterToNumber()
{
  if(!strcmp (buffer2, "0")) return(0);
  if(!strcmp (buffer2, "1")) return(1);
  if(!strcmp (buffer2, "2")) return(2);
  if(!strcmp (buffer2, "3")) return(3);
  if(!strcmp (buffer2, "4")) return(4);
  if(!strcmp (buffer2, "5")) return(5);
  if(!strcmp (buffer2, "6")) return(6);
  if(!strcmp (buffer2, "7")) return(7);
  if(!strcmp (buffer2, "8")) return(8);
  if(!strcmp (buffer2, "9")) return(9);
}
Kristopher Kortright
Father, Husband, Horseman, Maker, Writer, Internet Technologist and Inventor of Strange of Useful Things
Supporter of the Open Source Hardware movement
User avatar
miax
 
Posts: 134
Joined: Tue Apr 05, 2011 10:41 am

Re: How to convert a string to a number

by Len17 on Sat Dec 31, 2011 11:08 pm

Yes, atol() does 32-bit numbers. The number in my example has 32 significant bits, and it's printed to the serial port to prove that it works right. :)
User avatar
Len17
 
Posts: 393
Joined: Sat Mar 14, 2009 6:20 pm

Re: How to convert a string to a number

by miax on Sun Jan 01, 2012 12:09 am

Awesome, Thanks again Len!

I'll try that out and report back on how it works. :)

Cheers,

Kris
User avatar
miax
 
Posts: 134
Joined: Tue Apr 05, 2011 10:41 am

Re: How to convert a string to a number

by miax on Sun Jan 01, 2012 5:58 am

Lin,

atol() works like a charm. :) Thank you! You just shorted my code by almost 100 lines!

The longer method however did not seem to work, not that I need it, but here are some results:

NewConverter starting with [35233681], atol = (35233681), long method: (4030294960), OldStype :[35233681]

Thanks again for all the help. :)

Cheers!

Kris
User avatar
miax
 
Posts: 134
Joined: Tue Apr 05, 2011 10:41 am

Re: How to convert a string to a number

by Len17 on Sun Jan 01, 2012 2:29 pm

From your code, I see you're using null-terminated strings, so atol() is the right way to go.

The other method is for fixed-length data. It knows how many digits there are so it just adds them all up. But in your case, your buffer has the digits ("35233681") followed by a null char and a few random unused bytes. Adding up all that will not give you the right answer.
User avatar
Len17
 
Posts: 393
Joined: Sat Mar 14, 2009 6:20 pm

Re: How to convert a string to a number

by stephanie on Sun Jan 01, 2012 6:26 pm

I don't know if this is re-inventing the wheel but this is the function I use for converting a string object to an integer value. In a sketch I was working on, I was using string objects rather than char arrays, and atoi didn't work with the string objects. This simple function just converts the string to a null terminated char array then uses atoi on that.

Cheers!

Code: Select all | TOGGLE FULL SIZE
int stringToNumber(String thisString) {
  int i, value, length;
  length = thisString.length();
  char blah[(length+1)];
  for(i=0; i<length; i++) {
    blah[i] = thisString.charAt(i);
  }
  blah[i]=0;
  value = atoi(blah);
  return value;
}
User avatar
stephanie
 
Posts: 295
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada

Re: How to convert a string to a number

by philba on Sun Jan 01, 2012 10:40 pm

If you're going to iterate over the string, might as well just add it up. Faster and smaller.

Code: Select all | TOGGLE FULL SIZE
int stringToNumber(String thisString) {
  int i, value = 0, length;
  length = thisString.length();
  for(i=0; i<length; i++) {
    value = (10*value) + thisString.charAt(i)-(int) '0';;
  }
  return value;
}
philba
 
Posts: 387
Joined: Mon Dec 19, 2011 5:59 pm

Re: How to convert a string to a number

by waspinator on Tue Mar 05, 2013 12:42 pm

Code: Select all | TOGGLE FULL SIZE
// convert arduino String to int
int stringToInt(String string){
 
  char char_string[string.length()+1];
  string.toCharArray(char_string, string.length()+1);
 
  return atoi(char_string);
}
waspinator
 
Posts: 1
Joined: Thu Oct 06, 2011 7:49 pm

Re: How to convert a string to a number

by miax on Thu Mar 07, 2013 5:26 pm

Thanks for the replys! :) Unfortunately real-life took alot more of my time last year than in previous years, and I didn't really get alot of "Making" done in Q3/Q4 2012 and the first part of this year. Since then I've fallen in love with Robotics, and have had to weigh the pro's and con's of continuing/completing a number of projects I was working on. Had I been lucky-enough to work for a real Maker company, I'm sure my time would be much more Maker-involved.

As it stands, I have not worked on XNP for many months! As I learned more and more about XBee, I found it was alot easier and more efficient to use the built-in XBee mesh protocols that are available with the Series-2 pro modules. They cost a few more bucks per unit, but all packet processing is off-loaded on the XBee chip, leaving the micro-controller free to do other things. I plan to release a final version of XNP sometime this year, depending on my work, home and hobby/project schedule, but honestly the XBee protocols are making huge strides in capability, and XNP may or may not make sense anymore.

Still the challenge of converting strings to numbers At Very High Speed is always a good one, and I appreciate the responses! :)

Cheers,

Kris
Kristopher Kortright
Father, Husband, Horseman, Maker, Writer, Internet Technologist and Inventor of Strange of Useful Things
Supporter of the Open Source Hardware movement
User avatar
miax
 
Posts: 134
Joined: Tue Apr 05, 2011 10:41 am