## How to convert a string to a number Moderators: adafruit_support_bill, adafruit

How to convert a string to a number

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()
{
}

Len17

Posts: 393
Joined: Sat Mar 14, 2009 6:20 pm

Re: How to convert a string to a number

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

miax

Posts: 134
Joined: Tue Apr 05, 2011 10:41 am

Re: How to convert a string to a number

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

miax

Posts: 134
Joined: Tue Apr 05, 2011 10:41 am

Re: How to convert a string to a number

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. :)

Len17

Posts: 393
Joined: Sat Mar 14, 2009 6:20 pm

Re: How to convert a string to a number

Awesome, Thanks again Len!

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

Cheers,

Kris

miax

Posts: 134
Joined: Tue Apr 05, 2011 10:41 am

Re: How to convert a string to a number

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

miax

Posts: 134
Joined: Tue Apr 05, 2011 10:41 am

Re: How to convert a string to a number

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.

Len17

Posts: 393
Joined: Sat Mar 14, 2009 6:20 pm

Re: How to convert a string to a number

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;
}

stephanie

Posts: 295
Joined: Sat Dec 11, 2010 12:17 am

Re: How to convert a string to a number

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

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

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

miax

Posts: 134
Joined: Tue Apr 05, 2011 10:41 am