sprintf - ignore my format attributes

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?

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);

I'm sure the fine folks over at snippets-r-us will have some answers for you.

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.