Pages: [1]   Go Down
Author Topic: Passing a string to a function/sub  (Read 1310 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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;

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

Thanks for your help guys...!  smiley
Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Strings are evil.  Don't use them.

Whenever possible, use character arrays (char *).
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Thanks!
Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

For your function, I would do something like:

Code:
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());
« Last Edit: December 04, 2012, 03:48:03 pm by majenko » Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

I sometimes just want to '

Code:
wltl("blaaat");

Without having to:
Code:
wltl("blaaat" ,"");

To make it all work.

Is there not a way to combine the string before passing it to the function?
« Last Edit: December 04, 2012, 04:06:04 pm by Lectere » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

And why exactly are strings evil?
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

I sometimes just want to '

Code:
wltl("blaaat");

Without having to:
Code:
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:

Code:
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);
}
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okey,

But what if I want to pass 5 arguments;

Code:
  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?

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep, you are passing the pointer.

You can construct a string using sprintf:

for example:
Code:
char temp[100];

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

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 323
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Majenko, Drone, thanks a lot! smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I get this error tho;

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

Code:
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;

Code:
  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.
« Last Edit: December 04, 2012, 06:06:10 pm by Lectere » Logged

0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 323
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I get this error tho;

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

Code:
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;

Code:
  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):

Code:
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.

 
Logged

Pages: [1]   Go Up
Jump to: