Char initialized as concatenation of String +String variables generates error

I am trying to insert a string into a char with concatenation and not getting any love from the Arduino compiler. It is over my head. Here is the code:

String strClient_id = "ESP8266-"+WiFi.macAddress().substring(9,11)
                                +WiFi.macAddress().substring(12,14)
                                +WiFi.macAddress().substring(15);


char mqtt_door_open_topic[60] = "stat/"+strClient_id.c_str()+"/garage/door1/reedswitch";

Here is the error:

 error: invalid operands of types 'const char [6]' and 'const char*' to binary 'operator+'

 char mqtt_door_open_topic[60] = "stat/"+strClient_id.c_str()+"/garage/door1/reedswitch";

                                                            ^

I've search and tried several variations, but I just end up generating different errors. For instance, if I just use strClient_id instead of strClient_id.c_str(), I get this error:

error: array must be initialized with a brace-enclosed initializer

 char mqtt_door_open_topic[60] = "stat/"+strClient_id+"/garage/door1/reedswitch";

                                                      ^

Any help appreciated.

char mqtt_door_open_topic[60]

doesn't define a String object but a character array (also called C string sometimes). On a character array you cannot use the "+" operator but you have to use the corresponding functions to manipulate it. Concatenating is done by the strcat function, you should use the strncat version.

Watch out for the String class and the + operator. The Arduino has limited RAM and no garbage collection so when you start allocating longer and longer Strings you end up with a heap memory that is shot full of holes. This can eventually lead to a crash. Best bet would be to stick to char arrays throughout and avoid the String class entirely on this type of platform.

@pylon, I will go research the strncat() function now.

@Delta_G, how would you accomplish the above using only char?

JSCSJSCS:
@Delta_G, how would you accomplish the above using only char?

Don't have enough code to tell. But given that the String class is nothing more than a syntax wrapper and behind the scenes uses char arrays itself, I'm absolutely certain that there is nothing you can do with String that you can't do with char arrays.

JSCSJSCS:
@Delta_G, how would you accomplish the above using only char?

With strncat() and maybe some of the other c string functions (you'll find them when you look up strncat() )

Thank you all, I will go research char data type concatenation.

I was not able to get done what I wanted with strcat or strncat. I could not find a way to concatenate char and Strings using these functions because they require the source and destination to be of type char and I could not figure out how to change a char to a String or vice versa. Very confusing. Then I found the toCharArray() method. It turned out to be the problem solver.

#include <ESP8266WiFi.h>

char client_id[15];

createClientId();

void createClientId(){
  strcat(client_id,"ESP8266-");
  char temp[3];
  WiFi.macAddress().substring(9,11).toCharArray(temp,3);
  strcat(client_id,temp);
  WiFi.macAddress().substring(12,14).toCharArray(temp,3);
  strcat(client_id,temp);
  WiFi.macAddress().substring(15).toCharArray(temp,3);
  strcat(client_id,temp);
}

Any suggestions to clean up/shorten, correct mistakes in this noobie code welcomed! Thanks again for the help everyone.

I was not able to get done what I wanted with strcat or strncat. I could not find a way to concatenate char and Strings using these functions

The real answer is to get rid of the String instances. See my posts above for why. Make both source and destination be a char from the beginning.

You seem to be building a bunch of stuff into a big string. Google "sprintf"

I can't do anything about that as far as I know. The wifi.macaddress() call returns a String. If Arduino had another library that give a wifi device's MAC address as a char array, I would love to hear about it.

I can't do anything about that as far as I know. The wifi.macaddress() call returns a String. If Arduino had another library that give a wifi device's MAC address as a char array, I would love to hear about it.

To be exact: The Arduino WiFi class doesn't have the macaddress() method so don't blame Arduino for someone else's fail.

Using the String class on the ESP8266 may be less of a problem than on the Arduino because the ESP8266 has much more RAM so wasting a few bytes for that class may be acceptable.

@pylon, Thank you for the clarification. I looked into this further and you are correct. I am using the WiFi.macAddress() from ESP8266WiFi.h.

Arduino does have it’s own WiFi.macAddress():

https://www.arduino.cc/en/Reference/WiFiMACAddress

Arduino’s WiFi.macAddress() returns a byte array however (better than a string as you say), while ESP8266WiFi.h returns a string.

I have edited my previous post’s code to make this clear.

ESP8266WiFi.h returns a string.

Do you mean a string or a String ?

I meant String. From ESP8266WiFi.cpp

String ESP8266WiFiSTAClass::macAddress(void) {
    uint8_t mac[6];
    char macStr[18] = { 0 };
    wifi_get_macaddr(STATION_IF, mac);

    sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    return String(macStr);
}