Passing a string to a function/sub

I've made a function to write a line to the log;

void wltl(String logmessage) { // write line to log
          if(DEBUG){
           Serial.println(String(hour()) + ":" + String(minute()) + ":" + String(second()) + " " + logmessage);
          }
}

But I get some strange results when I run this.

I call it like this;

  wltl("SSID: " + String(WiFi.SSID()));

Thanks for your help guys...! :slight_smile:

Strings are evil. Don't use them.

Whenever possible, use character arrays (char *).

Is that because they can't be of variable lenght?,

And with a char array, how exactly would you write the log routine?

Thanks!

They can be of variable length, but they stomp all over your memory. Not nice.

For your function, I would do something like:

void wltl(char *facility, char *logmessage) 
{ // write line to log
  if (DEBUG) {
    Serial.print(hour());
    Serial.print(":");
    Serial.print(minute());
    Serial.print(":");
    Serial.print(second());
    Serial.print(" ");
    Serial.print(facility);
    Serial.print(": ");
    Serial.println(logmessage);
  }
}

wltl("SSID", WiFi.SSID());

But this forces me to allways pass 2 arguments to the function,

I sometimes just want to '

wltl("blaaat");

Without having to:

wltl("blaaat" ,"");

To make it all work.

Is there not a way to combine the string before passing it to the function?

And why exactly are strings evil?

1 Like

They use C's memory allocation routines behind the scenes. There is a bug in the implementation of free, which will eventually use all your memory and crash. Even if the bug were fixed, there would still be a risk of problems caused by heap fragmentation. C arrays of char are a much better idea.

Lectere:
But this forces me to allways pass 2 arguments to the function,

I sometimes just want to '

wltl("blaaat");

Without having to:

wltl("blaaat" ,"");

To make it all work.

Is there not a way to combine the string before passing it to the function?

There is, but it involves more memory, and is pretty pointless anyway. You could overload:

void wltl(char *facility, char *logmessage) 
{ // write line to log
  if (DEBUG) {
    Serial.print(hour());
    Serial.print(":");
    Serial.print(minute());
    Serial.print(":");
    Serial.print(second());
    Serial.print(" ");
    if(facility)
    {
      Serial.print(facility);
      Serial.print(": ");
    }
    Serial.println(logmessage);
  }
}

void wltl(char *logmessage) 
{
  wltl(NULL,logmessage);
}

Okey,

But what if I want to pass 5 arguments;

  wltl("IP Address: " + String(ip[0]) + "." + String(ip[1]) + "." + String(ip[2]) + "." + String(ip[3]));
  wltl("Signal strenght (RSSI): " + String(WiFi.RSSI()) + "dBm");

Do I have to write 5 overload routines?

It this all because you are passing a pointer to the string, and not the actual string?

Yep, you are passing the pointer.

You can construct a string using sprintf:

for example:

char temp[100];

sprintf(temp,"%d:%d:%d %s: %s",hour(),minutes(),seconds(),facility,logmessage);

You are not passing five arguments, you are passing one argument and using the overloaded + operator of the String class to construct that argument. Stop putting that operator in the argument, either construct your new string first, or pass multiple strings as multiple arguments.

Majenko, Drone, thanks a lot! :slight_smile:

I get this error tho;

error: cannot convert 'StringSumHelper' to 'char*' for argument '1' to 'void wltl(char*)'

void wltl(char *logmessage) { // write line to log
          if(DEBUG){
            Serial.print(hour());
            Serial.print(":");
            Serial.print(minute());
            Serial.print(":");
            Serial.print(second());
            Serial.print(":");
            Serial.println(logmessage);
          }
}

And I call it with this;

  wltl("IP Address: " + String(ip[0]) + "." + String(ip[1]) + "." + String(ip[2]) + "." + String(ip[3]));

The WLTL routine is suppose to make live easier, to centrally controll weather or not to write log items to disc, or add time stamps.

If I first have to construct a string, and then pass it, I might as well just plot it...

I'm a VB guy, I don't understand all this fuzz.

Lectere:
I get this error tho;

error: cannot convert 'StringSumHelper' to 'char*' for argument '1' to 'void wltl(char*)'

void wltl(char *logmessage) { // write line to log

if(DEBUG){
            Serial.print(hour());
            Serial.print(":");
            Serial.print(minute());
            Serial.print(":");
            Serial.print(second());
            Serial.print(":");
            Serial.println(logmessage);
          }
}




And I call it with this;



wltl("IP Address: " + String(ip[0]) + "." + String(ip[1]) + "." + String(ip[2]) + "." + String(ip[3]));




The WLTL routine is suppose to make live easier, to centrally controll weather or not to write log items to disc, or add time stamps.

How can you convert a complex object like String to a char pointer?

You can't.

"ABC" is a const char[3]. Get the plus operators out of your argument, as I said earlier.

Consider the following, as has already been indicated to you by majenko (get rid of String):

char logmsg[100];
sprintf(logmsg, "IP Address: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);

wltl(logmsg);

Your life will be simpler, and your sketch will be smaller.