Pages: [1]   Go Down
Author Topic: Problems passings strings to function with variable args  (Read 507 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 1
Posts: 126
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

#include <stdarg.h>

char *P(char *fmt, ... ){
   char tmp[128]; // resulting string limited to 128 chars
   va_list args;
   va_start (args, fmt );
   vsnprintf(tmp, 128, fmt, args);
   va_end (args);
   return tmp;
}

I am trying to pass a string from an array to this function

String XMLTagStrings[] = {
"data",
"temperature",
"humidity",
"dateTime"
};

char *data = P("%s",  XMLTagStrings[1]);
Serial.println(data);

I am not sure of the error as it compiles but I get nothing written to the serial port.

If I use the following it works, so I assume that the string below is passed as char *, whereas the other is a String

char *data = P("%s",  "Testing");
Serial.println(data);

I do not know how to translate this so it works with strings - any help appreciated.

Chris
Logged

Ayer, Massachusetts, USA
Offline Offline
Edison Member
*
Karma: 50
Posts: 1767
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#include <stdarg.h>

char *P(char *fmt, ... ){
char tmp[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt );
vsnprintf(tmp, 128, fmt, args);
va_end (args);
return tmp;
}

In the future, learn to use code tags (hit the '#' button), it helps people read your code.

Your problem is the tmp declaration is on the stack.  When you return, the stack is erased, and Serial.println will overwrite it.  I would suggest declaring it as:

Code:
static char tmp[128]; // resulting string limited to 128 chars

This says to put tmp in static storage which does not change between function invocations.
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 126
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the future, learn to use code tags (hit the '#' button), it helps people read your code.

Good call - I will keep it in mind.

Your problem is the tmp declaration is on the stack.  When you return, the stack is erased, and Serial.println will overwrite it.  I would suggest declaring it as:

Thanks but it does not fix the issue.

I think it may have something to do with passing a String to the function P

If I pass a constant string "CHRIS" then it works as expected, but if I put "Chris" into a String and pass that the function returns no data and for all I know never returns.

Any other ideas?

Chris
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 126
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Code:
#include <stdarg.h>

char *P(char *fmt, ... ){
   static char tmp[128]; // resulting string limited to 128 chars
   Serial.println("A");
   va_list args;
   Serial.println("B");
   va_start (args, fmt );
   Serial.println("C");
   vsnprintf(tmp, 128, fmt, args);
   Serial.println("D");
   va_end (args);
   Serial.println("E");

   delay(100);     
   return tmp;
}


void setup()
{
  Serial.begin(9600);
  Serial.println("Starting...");
}

void loop()
{
String XMLTagStrings[] = {
"data",
"temperature",
"humidity",
"dateTime"
};

  Serial.println("Before Call");
  delay(100);
char *data = P("%s",  "Chris");
//char *data = P("%s",  XMLTagStrings[1]);
  Serial.println("After Call");
Serial.println(data);
delay(1000);
}


This example shows the issue.

As is it will run but comment out the

Code:
char *data = P("%s",  "Chris");

and uncomment the

Code:
//char *data = P("%s",  XMLTagStrings[1]);

and you will see it never prints "A" inside the P function where it does with the previous call with a static string "Chris"

Hope this helps someone help me.

Chris
Logged

Ayer, Massachusetts, USA
Offline Offline
Edison Member
*
Karma: 50
Posts: 1767
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If I pass a constant string "CHRIS" then it works as expected, but if I put "Chris" into a String and pass that the function returns no data and for all I know never returns.

Any other ideas?
You can't pass String types to *printf functions.  It does not know about the String type.  Instead you have to convert String back to a char array, and pass that to your function and use %s with it.
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 126
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't pass String types to *printf functions.  It does not know about the String type.  Instead you have to convert String back to a char array, and pass that to your function and use %s with it.

After reading this i found that I could simply change my array and it is all happy now

Code:
static char *XMLTagStrings[] = {
"xml",
"temperature",
"humidity",
"dateTime"
};

Thanks

Chris
Logged

Pages: [1]   Go Up
Jump to: