Hi I am trying to format c string in char array using sprintf.
I have following code:
bool relay_status = false;
void setup() {
Serial.begin(9600);
}
void loop() {
char response[1024];
sprintf(response,
"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
"<!DOCTYPE HTML>\r\n<html>\r\n"
"<body style=\"font-size: 2em;\">\r\n"
"relay_status=%s\r\n",
"
<a href=\"/gpio/%c\">switch %s</a>\r\n"
"</body></html>",
(relay_status)?"high":"low", (relay_status)?'0':'1', (relay_status)?"off":"on"
);
Serial.println(response);
delay(3000);
}
Outpus is:
HTTP/1.1 200 OK
Content-Type: text/html
<!DOCTYPE HTML>
<html>
<body style="font-size: 2em;">
relay_status=
<a href="/gpio/%c">switch %s</a>
</body></html>
What I do bad?
system
January 8, 2017, 5:14pm
2
What I do bad?
I'm going to guess you used too much RAM
AWOL:
I'm going to guess you used too much RAM
I'm using ESP8266 wit a lot of ram.
If I use smaller buffer char response[256]; , still doesn't work.
With String it works great:
String r;
r += "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
r += "<!DOCTYPE HTML>\r\n<html>\r\n";
r += "<body style=\"font-size: 2em;\">\r\n";
r += "relay_status=";
r += (relay_status)?"high":"low";
r += "\r\n";
r += "
<a href=\"/gpio/";
r += (relay_status)?'0':'1';
r += "\">switch ";
r += (relay_status)?"off":"on";
r += "</a>\r\n";
r += "</body></html>";
Serial.println(r);
system
January 8, 2017, 5:31pm
5
I'm sure the fine folks over at snippets-r-us will have some answers for you.
dev_1
January 8, 2017, 5:43pm
6
There's no reason to put everything in one big buffer and print it with one statement. Just print the pieces:
Serial.print
(
"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
"<!DOCTYPE HTML>\r\n<html>\r\n"
"<body style=\"font-size: 2em;\">\r\n"
"relay_status="
);
Serial.print( (relay_status) ? "high" : "low" );
Serial.print
(
"\r\n"
"
<a href=\"/gpio/"
);
Serial.print( (relay_status) ? '0' : '1' );
Serial.print( "\">switch " );
Serial.print( (relay_status)?"off":"on" );
Serial.println
(
"</a>\r\n"
"</body></html>"
);
(Adjacent double-quoted string literals are treated as one concatenated literal.)
And yes, the String
can also get you into memory trouble on the ESP8266.
Cheers,
/dev
martin159:
bool relay_status = false;
void setup() {
Serial.begin(9600);
}
void loop() {
char response[1024];
sprintf(response,
"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
"\r\n\r\n"
"<body style="font-size: 2em;">\r\n"
"relay_status=%s\r\n",
"
<a href="/gpio/%c">switch %s\r\n"
"",
(relay_status)?"high":"low", (relay_status)?'0':'1', (relay_status)?"off":"on"
);
Serial.println(response);
delay(3000);
}
You are trying to get sprintf to work not just for the first format string but also the next string.
This is the format string,
"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
"<!DOCTYPE HTML>\r\n<html>\r\n"
"<body style=\"font-size: 2em;\">\r\n"
"relay_status=%s\r\n",
This is not, so why the format chars in it?
"
<a href=\"/gpio/%c\">switch %s</a>\r\n"
"</body></html>",
The better question is WHY bother using a completely unnecessary array and sprintf there at all?
Serial goes out one bit at a time, each char takes many cycles to send. You can print single chars and still overfill the output buffer before a single char is sent. Break that up and print pieces, it will still be received the same as if it was all sent from a prepared buffer for instant transmission (an unreal notion).
martin159:
What I do bad?
What is the comma doing in
"relay_status=%s\r\n",
??
That indicates the end of the format string and anything after that is arguments to the format string. So the the %s will be replaced by
"
<a href=\"/gpio/%c\">switch %s</a>\r\n"
"</body></html>"
and
(relay_status)?"high":"low", (relay_status)?'0':'1', (relay_status)?"off":"on"
will be ignored as there is only one format specifier in the format string.