Combining char arrays

Hello folks, I am currently programming an ESP32 and have trouble combining different char arrays.

I have these variables for example:

char mID[3] ="13";
char shelly = "http://192.168.0.1";
char relais = "/relay/0? HTTP/1.1";

and I want to combine these char array into one that looks like this:

"http://192.168.0.113/relay/0? HTTP/1.1"

Im complety surprised that this is such a huge problem in C and really pissed off I allready tried many examples in google like strcat() or whatever but it does not work as intended.

Does anybody of you has an idea or working example?

(Im doing this so i dont have to change X lines when the IP changes and only have to change mID in code)

sincerly Alexander

strcat() and its variants do indeed work. So, it would be best if you posted the code where you attempted to use it. Someone here can then point out what you did wrong.

PS -- Post your code with Code Tags. If you don't know what that means, read the forum guidelines first.

char mID[3] ="17";
char shelly = "http://192.168.0.1";
char shellyOff = "http://192.168.0.1";
char relais = "/relay/0? HTTP/1.1";
char off = "/relay/0?turn=off HTTP/1.1";

strcat (shelly, mID);
strcat (shelly, relais);
strcat (shellyOff, mID);
strcat (shellyOff, off);

output looks like this wtf?

shelly:
13:52:41.621 -> http://192.168.0.17/relay/0? HTTP/1.1/relay/0?turn=off HTTP/1.1
shellyOff
13:52:41.714 -> /relay/0? HTTP/1.1/relay/0?turn=off HTTP/1.1

consider following code producing

http://192.168.0.1
/relay/0? HTTP/1.1
http://192.168.0.1/relay/0? HTTP/1.1

char s [80];
const char shelly [] = "http://192.168.0.1";
const char relais [] = "/relay/0? HTTP/1.1";

void
setup ()
{
    Serial.begin (9600);

    strcpy (s, shelly);
    strcat (s, relais);

    Serial.println (shelly);
    Serial.println (relais);
    Serial.println (s);
}

void
loop ()
{
}

@ alex3480, please read the forum guidelines (you should have done this before posting your question) and post your code properly with Code Tags.

BTW, you're writing beyond the end of the 'shelly' array into memory that you don't own.

I have to be honest I dont really seem to understand these functions but I think ts working now.


char mID[3] ="17";
char shelly[128]; 
char shellyOff[128];
char ip[] =  "http://192.168.0.1";
char relais[] = "/relay/0? HTTP/1.1";
char off[] = "/relay/0?turn=off HTTP/1.1";

  strcpy (shelly,ip);
  strcat (shelly,mID);
  strcat (shelly, relais);
  strcpy (shellyOff, ip);
  strcat (shellyOff, mID);
  strcat (shellyOff, off);

Is the memory problem fixed if I do it like this?

Thanks for your help :slight_smile:

Looks much better.

strcat needs to append to something. could be a null string

Global variables are initialized to 0. But this would certainly be preferable:

char shelly[128] = {0};

Or (to your point), even better:

char shelly[128] = "";
1 Like

Yes, as long as the resulting string is never longer than 127 bytes.

Avoid strcat() as it can easily overflow, particularly in your case where you are adding multiple strings.
Instead use strlcat() which protects against overflows and crashes.
see this sketch strlcpy_strlcat.ino
for examples of how to use

Or for simple robust code use Arduino Strings and avoid memory problems

char mID[3] ="17";
String shelly; 
String shellyOff;
char ip[] =  "http://192.168.0.1";
char relais[] = "/relay/0? HTTP/1.1";
char off[] = "/relay/0?turn=off HTTP/1.1";

  shelly = ip;
  shelly += mID;
  shelly += relais;
  // then shelly.c_str() will return the char[   ] holding the result
char* result = shelly.c_str();

  shellyOff = ip;
  shellyOff += mID;
  shellyOff += off;
  // then shellyOff.c_str() will return the char[   ] holding the result
char* resultOff = shellyOff.c_str();

OR
if you want to keep using char[ ]s like shelly[128] you can wrap them in a SafeString which protects against buffer overflows and has nice error messages.

#include "SafeString.h"
char mID[3] ="17";
char shelly[128]; 
char shellyOff[128];
char ip[] =  "http://192.168.0.1";
char relais[] = "/relay/0? HTTP/1.1";
char off[] = "/relay/0?turn=off HTTP/1.1";

  cSFA(sfShelly,shelly); // wrap shelly in a SafeString, which directly updates shelly[ ] char array
  sfShelly = ip;
  sfShelly += mID;
  sfShelly += relais;
  // then shelly[..] will be holding the result
  Serial.println(shelly);

  cSFA(sfShellyOff,shellyOff); // wrap shellyOff in a SafeString, which directly updates shellyOff[ ] char array
  sfShellyOff = ip;
  sfShellyOff += mID;
  sfShellyOff += off;
   // then shellyOff[..] will be holding the result
  Serial.println(shellyOff);