87

I am getting an int value from one of the analog pins on my Arduino. How do I concatenate this to a String and then convert the String to a char[]?

It was suggested that I try char msg[] = myString.getChars();, but I am receiving a message that getChars does not exist.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris
  • 5,485
  • 15
  • 68
  • 130
  • 8
    Do you really need a modifiable array? If not, you could use `const char * msg = myString.c_str();`. Unlike `toCharArray()`, `c_str()` is a zero-copy operation, and zero-copy is a good thing on memory-constrained devices. – Edgar Bonet Feb 14 '15 at 09:44
  • @EdgarBonet It works, but only for one string at time. Last c_str() overwrite older. – mmv-ru May 10 '19 at 02:27

5 Answers5

139
  1. To convert and append an integer, use operator += (or member function concat):

     String stringOne = "A long integer: ";
     stringOne += 123456789;
    
  2. To get the string as type char[], use toCharArray():

     char charBuf[50];
     stringOne.toCharArray(charBuf, 50)
    

In the example, there is only space for 49 characters (presuming it is terminated by null). You may want to make the size dynamic.

Overhead

The cost of bringing in String (it is not included if not used anywhere in the sketch), is approximately 1212 bytes of program memory (flash) and 48 bytes RAM.

This was measured using Arduino IDE version 1.8.10 (2019-09-13) for an Arduino Leonardo sketch.

Risk

There must be sufficient free RAM available. Otherwise, the result may be lockup/freeze of the application or other strange behaviour (UB).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 13
    Saved me a lot of tinkering time. Thanks! In order to make the char[] size dynamic, do something like `char charBuf[stringOne.length()+1]` – loeschg Mar 23 '12 at 19:37
  • 9
    I did it dynamically like this: `char ssid[ssidString.length()];` `ssidString.toCharArray(ssid, ssidString.length());` – dumbledad Dec 14 '12 at 13:45
  • 1
    @loeschg Thanks, I tried without the `+1` at first, but your solution worked for me! – Blundering Philosopher Apr 18 '14 at 18:57
  • https://developercommunity.visualstudio.com/idea/365434/edit-comments-on-tickets-discussion.html?childToView=397510#comment-397510 – Peter Mortensen Dec 04 '18 at 18:37
  • BIG WARNING! I learned the hard way, if you're intent is to get a partial string, let's say the first character only to use in a switch/case statement, you need to allocate enough for the whole string, otherwise the function returns and leaves your buffer empty - and you scratching your head and ending up in this forum. – Danny Holstein Feb 13 '20 at 17:09
  • Though 48 bytes RAM is suspicious close to the buffer size. This needs to be investigated. Coming up. – Peter Mortensen Jun 30 '22 at 13:37
60

Just as a reference, below is an example of how to convert between String and char[] with a dynamic length -

// Define 
String str = "This is my string"; 

// Length (with one extra character for the null terminator)
int str_len = str.length() + 1; 

// Prepare the character array (the buffer) 
char char_array[str_len];

// Copy it over 
str.toCharArray(char_array, str_len);
 

Yes, this is painfully obtuse for something as simple as a type conversion, but somehow it's the easiest way.

Numan Gillani
  • 489
  • 9
  • 19
Alex King
  • 2,504
  • 23
  • 26
23

You can convert it to char* if you don't need a modifiable string by using:

(char*) yourString.c_str();

This would be very useful when you want to publish a String variable via MQTT in arduino.

Linh Le Vu
  • 436
  • 4
  • 7
1

None of that stuff worked. Here's a much simpler way .. the label str is the pointer to what IS an array...

String str = String(yourNumber, DEC); // Obviously .. get your int or byte into the string

str = str + '\r' + '\n'; // Add the required carriage return, optional line feed

byte str_len = str.length();

// Get the length of the whole lot .. C will kindly
// place a null at the end of the string which makes
// it by default an array[].
// The [0] element is the highest digit... so we
// have a separate place counter for the array...

byte arrayPointer = 0;

while (str_len)
{
    // I was outputting the digits to the TX buffer

    if ((UCSR0A & (1<<UDRE0))) // Is the TX buffer empty?
    {
        UDR0 = str[arrayPointer];
        --str_len;
        ++arrayPointer;
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

With all the answers here, I'm surprised no one has brought up using itoa already built in.

It inserts the string representation of the integer into the given pointer.

int a = 4625;
char cStr[5];       // number of digits + 1 for null terminator
itoa(a, cStr, 10);  // int value, pointer to string, base number

Or if you're unsure of the length of the string:

int b = 80085;
int len = String(b).length();
char cStr[len + 1];  // String.length() does not include the null terminator
itoa(b, cStr, 10);   // or you could use String(b).toCharArray(cStr, len);