Problems passings strings to function with variable args

#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

iisfaq:

#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:

	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.

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

MichaelMeissner:
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

#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

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

and uncomment the

//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

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

MichaelMeissner:
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

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

Thanks

Chris