1

I'm using sprintf to use a format specifier myTemplate with some strings. The result will then be written to Serial. Although the sketch compiles fine, it does not write any thing to the serial, nothing is seen in the Serial monitor.

Is sprintf being used wrongly here?

char* result;
char* myTemplate;

void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
}

void loop() {
    myTemplate = "Welcome %s. You have slept %s times";
    sprintf(result, myTemplate, "Jane", "many");
    Serial.println(result);
    Serial.println("hello");

}

When I try the follwing sketch and write something to the Serial monitor, I receive gibberish echoed back to me! Why is this?

Sketch

char received;
char* message = "";

void setup() {
    Serial.begin(9600);
}

void loop() {

    // Echos back
    if(Serial.available() > 0) {
        received = Serial.read();
        Serial.println(message);


        if(received == '\n') {
            message = "";
        }  else {
            message += received;
        }


    }
}   
  • Where do you actually allocate any memory to result? – Ignacio Vazquez-Abrams Mar 31 '14 at 0:59
  • define 'gibberish'. Can you give some examples of what you are receiving? Have you got the monitor on 9600 as well? You realise you're Serial.printing message before you're allocating your read to it? And that at the end of the read there is possibly a new line which clears your message anyway, so it's never going to be seen – Madivad Mar 31 '14 at 16:54
3

When you use sprintf(), you need to have some space allocated for it to write the result to. At the moment, you're just passing an uninitialised pointer (result), meaning the behaviour of sprintf() is undefined. It might appear to work under some circumstances, but not others (and even if it did seem to work, it could have some nasty side effects on other parts of your code).

The simplest approach is to allocate a static char buffer. You need to be sure it's big enough to contain all of the text you want it to store though (plus an extra null character at the end).

For example:

char* myTemplate = "";
char result[64] = {0};

void setup() {
    Serial.begin(9600);
}

void loop() {
    myTemplate = "Welcome %s. You have slept %s times";

    sprintf(result, myTemplate, "Jane", "many");
    Serial.println(result);
    Serial.println("hello");
}

As a side note, it's usually a good idea to initialise your variables. This is especially true for pointers.

| improve this answer | |
  • Unfortunately it isn't quite always good to initialize them. Initializing them (or leaving them with the default value) will add prologue code to set/clear them even if the original value is never used; to prevent this declare the variable as being uninitialized, e.g. char *result __attribute__ ((section (".noinit")));. See the "Memory Sections" section of the AVR Libc documentation for details. – Ignacio Vazquez-Abrams Mar 31 '14 at 1:18
  • Thank you. When I try to empty out message using message="", I get the error in the (updated) question. Whats the proper way to clear a buffer? – Nyxynyx Mar 31 '14 at 2:59
  • @Nyxynyx: Why do you need to clear it? – Ignacio Vazquez-Abrams Mar 31 '14 at 3:06
  • 3
    Oh boy... Unfortunately string handling in C is not quite as simple as you try to make it. Consider using string or String instead. – Ignacio Vazquez-Abrams Mar 31 '14 at 3:10
  • 1
    Handling C strings is a bit out of scope for this site. Consider reading through C string questions on Stack Overflow for some insight on how they work. – Ignacio Vazquez-Abrams Mar 31 '14 at 3:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.