How does printf() function treat the strings returned by functions using global buffers?

  • A+
Category:Languages

I have written a small code that prints the current date with a specific format. To return each data of the date (day of the week, day of the month, name of the month, etc.), I use functions of type const char * that pass the data as a string to a variable that serves as a buffer and then pass the buffer to the main function.

The following code represents the operation of my program in a very simple way:

#include <stdio.h> #include <string.h>  char buff[16];  const char *printStr1 (char *str1) {     strncpy(buff, str1, sizeof(str1));     return buff; };  const char *printStr2 (char *str2) {     strncpy(buff, str2, sizeof(str2));     return buff; };   int main() {     printf("%s%s", printStr1("foo"), printStr2("bar"));     return 0; } 

My issue is this: when passing each data to the buffer and returning it to the main function, the last two data are the same (the last data is not printed, instead it is printed what was already in the buffer, that is, the second last data).

This only happens when I use a single printf() function to show all the data, as in the example above. If I do not use a buffer to return the data (I directly return the argument passed to the function) or use a printf() for every data , everything is executed correctly.

P.S.: I tried to solve this using functions like memset() to clean the buffer, but it does not work, the only thing I can do is use a different buffer for each data (for each function).

I hope I have expressed my problem well.

 


besides the sizeof issue (that you're overlooking because your strings are small), your issue isn't related to printf

The code first evaluates the arguments, then passes them to printf. The last evaluated argument "wins" and printf gets the same argument twice.

To use only one local buffer, split your printf call:

printf("%s%s", printStr1("foo"), printStr2("bar")); 

could be rewritten to:

printf("%s", printStr1("foo")); printf("%s", printStr2("bar")); 

once printed the value can change it doesn't matter :)

Since C doesn't have a garbage collector or string objects, you cannot just allocate separate buffers and return them to pass to printf else you'd get memory leaks, so in C there's no smart & readable solution for such issues.

That said, in one C project I made, I used a revolving list of strings (several buffers, first in, first out). Make it 10 buffers, and you can use up to 10 arguments in the same function and it will work properly.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: