Arduino int to string: How to convert an integer to a string. Find
out the standard form and Learn how to code it yourself. Also find the
one subtle error you missed.
Arduino int to string - find out:
The standard function for int to string conversion.
The algorithm used to do the conversion.
Exactly how to code it yourself.
A subtle hidden error in some external code.
How to use the itoa function to convert an integer into a string.
If you want to know how it really does its
magic, this page will also show you fundamental code for
Arduino int to strings conversion.
Standard form of Arduino int to string
The function you need is itoa() which has the prototype:
char *itoa( int value, char *str, int base);
Where:
value - is the integer to change into a string.
str - is a string buffer that stores the string.
base - is the conversion radix.
The function takes the above arguments and returns a string (it is basically the same string buffer that you gave it!).
You supply the integer value, a pointer to buffer that will store the string
'str' and then specify the base which can be any number, but common
ones are:
10 for
decimal,
16 for hexadecimal,
2 for binary
The base can be any integer - but
you'll get odd characters above 36 - and eventually run out of characters!
The name of the function is an acronym for int toASCII - itoa.
Where ASCII is another acronym standing for American Standard Code for Information Interchange. It defines is a table of characters.
String Buffer length
The string buffer must allow room for the maximum characters that can be created when converting an integer.
Warning: Allow for the maximum string output in your buffer.
If you don't you could overwrite other variables causing random output!
For example a decimal string requires 5 characters,
space for a minus sign, and a null termination '\0'. So a buffer of
length 7.
Hexadecimal requires 4 characters and a null termination '\0'.
Binary requires 16 characters and a null termination '\0'.
Simple Arduino int to string example
static char buf[17];
char *convertBin( int v ) {
return itoa(v, buf, 2);
}
Fundamental Code: Arduino int to string conversion
Introduction
How to code itoa from first principles.
For the Arduino Uno, integers are defined as 16 bits long. The C
standard does not specify the length of an integer so for a different
chip e.g. a 32 bit processor such as the ESP32, an integer could have a
different length (probably 32 bits!).
If you really want to tie down the compiler use the type below:
int16_t <variable name>;
which (for the Uno) is the same as:
int <variable name>;
Both of the above are signed integers that use the two's complement representation of binary numbers.
It is important to know the length (in bits) of the integer since
that determines the maximum possible string length. That means you can
set the minimum required string buffer length in your code. So for an
integer, the range is:
-32768 ~ +32767
If this was an unsigned integer then the range would be:
0 ~ 65535 = pow(2,16)-1;
So for a signed integer, the maximum string length buffer required is 6
characters (including minus sign). Unsigned requires 5 characters.
The maximum buffer length for both signed and unsigned integers is 7 characters (including the null string terminator).
Arduino int to string Algorithm
Now you have the fundamental information on the input and output variables you can start to write the algorithm.
Storage:
uint16_t v
char buf[7];
First of all determine the sign and store that information
if (v<0) {
sign = 1;
v = -v;
}
Also normalize the number so you are working only with positive integers.
Since we use base 10 numbers the number we process will be divided by
10 each time around a loop - the remainder is the bit we store in the
buffer.
So lets say we have a number 12345 to convert into a string.
Repeat an integer division and store the remainder:
Maths
Result
Buffer content
12345/10
= 1234 remainder 5
buf[1] = 5
1234/10
= 123 remainder 4
buf[2] = 4
123/10
= 12 remainder 3
buf[3] = 3
12/10
= 1 remainder 2
buf[4] = 2
1/10
= 0 remainder 1
buf[5] = 1
0: Terminate
null terminate the string
buf[6] = '\0'
As you can see, the buffer content is reversed, so to finalise the
result you have to reverse the buffer content, remembering to add the
sign character if needed.
TIP: To get the remainder of an expression use the mathematical operator '%'.
Arduino int to string Code
//****************************************************
// Find more Arduino Projects and Tutorials at TronicsBench.com
//
// Written by John Main.
//
// MIT license, all text above must be included in any redistribution
// ****************************************************
// Special case if input is zero - display a zero!
if (v==0) {
str[0] = '0';
str[1] = '\0';
return str;
}
// // This commented-out code has a subtle problem
// if (v < 0)
// sign = 1;
// v = -v;
// }
// while (v) { // Number is not zero.
// *str++ = v % 10 + '0'; // zero = ascii '0'
// v /= 10;
// }
if (v < 0)
sign = 1;
while (v) { // Number is not zero.
*str++ =abs(v % 10) + '0'; // zero = ascii '0'
v /= 10;
}
// Add the sign character if needed.
if (sign)
*str++ = '-';
*str='\0';
// Now reverse the string
str--; // at last character.
while(p < str) { // stop at middle or past middle.
ch = *p; // temporary store.
*p = *str;
*str = ch;
p++; str--;
}
return buf;
}
void showValBuf(int v,char *buf) {
Serial.print("Input variable v is: ");
Serial.println(v);
Serial.print("String buffer is ");
Serial.println(buf);
Serial.println("~~~~");
}
void setup() {
static char buf[7];
Serial.begin(115200);
Serial.println("Dec to A");
int v = 12345;
dectoa(v,buf);
showValBuf(v,buf);
v = 102;
dectoa(v,buf);
showValBuf(v,buf);
v = 0;
dectoa(v,buf);
showValBuf(v,buf);
v = -4783;
dectoa(v,buf);
showValBuf(v,buf);
v = INT16_MAX;
dectoa(v,buf);
showValBuf(v,buf);
v = INT16_MIN;
dectoa(v,buf);
showValBuf(v,buf);
v = 40000;
dectoa(v,buf);
showValBuf(v,buf);
}
void loop() {
// put your main code here, to run repeatedly:
}
Ouptut from the code
Dec to A
Input variable v is: 12345
String buffer is 12345
~~~~
Input variable v is: 102
String buffer is 102
~~~~
Input variable v is: 0
String buffer is 0
~~~~
Input variable v is: -4783
String buffer is -4783
~~~~
Input variable v is: 32767
String buffer is 32767
~~~~
Input variable v is: -32768
String buffer is -32768
~~~~
Input variable v is: -25536
String buffer is -25536
~~~~
Note: The integer value 40000 is interpreted as a signed integer of value -25536.
A gotcha: Arduino int to string
I had a bit of trouble with this one and its useful for you to see how subtle problems can arise in any code.
I originally wrote that code as follows (commented out in above code):
if (v<0) {
sign = 1;
v = -v;
}
while (v) { // Number is not zero.
*str++ = v % 10 + '0'; // zero = ascii '0'
v /= 10;
}
Which has the intention of detecting a negative number and
normalising it to a positive one, so that only positive values are used
in the while loop. It means that the index into the ASCII array is
positive and depends on the positive remainder value.
This all sounds very reasonable until you actually test it!
All reasonable numbers work fine. But testing an unreasonable number at the limits of the signed integer type shows a problem:
Normal numbers are fine:
~~~~
Input variable v is: 12345
String buffer is 12345
~~~~
Input variable v is: -4783
String buffer is -4783
~~~~
...has no effect and does not make the value positive!
This is due to the operation of the two's complement addition.
Here v = -v results in the same negative number as -32768
can not be represented as a positive value! therefore the index into the
ASCII table is negative which is why garbage is output.
How to solve it
Since the % operator can work with negative values the
solution is to 'not' negate the variable v in the sign detection
condition, and instead use the abs function on the smaller index values
i.e.
Instead of :
*str++ = v % 10 + '0'; // zero = ascii '0'
you use:
*str++ =abs(v % 10) + '0'; // zero = ascii '0'
Note: This shows the importance of code testing and understanding of underlying operations.
Note: You can find the same error here:
https://www.geeksforgeeks.org/implement-itoa/
Full code with base control
The following code adds the ability to control the conversion radix (or
base). It gives you the same operation as the commonly used itoa function.
It means you can output a number in any base e.g. hexadecimal is
base 16, binary is base 2.
Note however that leading zeros are not output, and you must allow the
string buffer more room i.e. for a binary output there are a possible 16
characters!
//****************************************************
// Find more Arduino Projects and Tutorials at TronicsBench.com
//
// Written by John Main.
//
// MIT license, all text above must be included in any redistribution
// ****************************************************
char *_itoa(int16_t v , char *str, int base) {
char *p = str, *buf=str;
char ch;
byte sign = 0;
// Special case if input is zero
if (v==0) {
str[0] = '0';
str[1] = '\0';
return str;
}
if (v < 0 && base==10) // sign for decimal only.
sign = 1;
while (v) { // Number is not zero.
int rem = abs(v % base);
// Set index into ASCII - numbers over 9 start from 'A'
ch = '0';
if (rem>9) {
rem -=10;
ch = 'A';
}
*str++ = rem + ch; // zero = ascii '0'
v /= base;
}
// Add the sign character if needed.
if (sign)
*str++ = '-';
*str='\0';
// Now reverse the string
str--; // at last character.
while(p < str) { // Stop at middle or past middle.
ch = *p; // temporary store.
*p = *str;
*str = ch;
p++; str--;
}
return buf;
}
void showValBuf(int v,char *buf) {
Serial.print("Input variable v is: ");
Serial.println(v);
Serial.print("String buffer is ");
Serial.println(buf);
Serial.println("~~~~");
}
void setup() {
int v;
char buf[27];
Serial.begin(115200);
Serial.println("Dec to A");
v = 12345;
_itoa(v,buf,10);
showValBuf(v,buf);
v = INT16_MIN;
_itoa(v,buf,10);
showValBuf(v,buf);
_itoa(v,buf,16);
showValBuf(v,buf);
v = INT16_MAX;
_itoa(v,buf,10);
showValBuf(v,buf);
_itoa(v,buf,16);
showValBuf(v,buf);
v = 0x7ffe;
_itoa(v,buf,16);
showValBuf(v,buf);
v = 102;
_itoa(v,buf,10);
showValBuf(v,buf);
v = 0;
_itoa(v,buf,10);
showValBuf(v,buf);
v = -4783;
_itoa(v,buf,10);
showValBuf(v,buf);
v = 40000;
_itoa(v,buf,10);
showValBuf(v,buf);
v = 0xff;
_itoa(v,buf,2);
showValBuf(v,buf);
v = 0x5a;
_itoa(v,buf,2);
showValBuf(v,buf);
}
void loop() {
// put your main code here, to run repeatedly:
}
Output from above code
Input variable v is: 12345
String buffer is 12345
~~~~
Input variable v is: -32768
String buffer is -32768
~~~~
Input variable v is: -32768
String buffer is 8000
~~~~
Input variable v is: 32767
String buffer is 32767
~~~~
Input variable v is: 32767
String buffer is 7FFF
~~~~
Input variable v is: 32766
String buffer is 7FFE
~~~~
Input variable v is: 102
String buffer is 102
~~~~
Input variable v is: 0
String buffer is 0
~~~~
Input variable v is: -4783
String buffer is -4783
~~~~
Input variable v is: -25536
String buffer is -25536
~~~~
Input variable v is: 255
String buffer is 11111111
~~~~
Input variable v is: 90
String buffer is 1011010
~~~~
Conclusions
The built in version works as expected; You can obtain a string version of an integer translated using any radix (number base).
Remember to allow enough characters in the buffer string to accept
the maximum conversion length - which varies depending on the radix!
TIP: Make sure the buffer is long enough or risk run time errors.
You have learned, from this page, how to code the Arduino int to string function - itoa - from first principles.
If you code it yourself there are unexpected subtle
problems (explored above) that are not to easy to solve or debug. They
are solved above and give you a good idea of what it takes to figure out
code/hardware.
Written by John Main, who has a degree in Electronic Engineering.
A PIR sensor lets your Arduino sense movement without contact. This tutorial covers PIR sensor basics, connecting one to an Arduino board and coding a motion detector.
Arduino Hall Effect Sensor: Add magnetic sensing superpowers to your Arduino projects with an easy-to-use hall effect sensor. With full code and layout...
Get started with an Arduino humidity sensor using the DHT11, which reports both humidity and temperature. Complete guide with full code for using this sensor
Comments
Have your say about what you just read! Leave me a comment in the box below.
Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.