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.
The printf() function sends a formatted string to the standard output (the display). This string can display formatted variables and special control characters, such as new lines ('\n'), backspaces ('\b') and tabspaces ('\t'); these are listed in Table 2.1.
The C library function int printf(const char *format, ...) sends formatted output to stdout.
The printf() and scanf() functions are used for input and output in C language. Both functions are inbuilt library functions, defined in stdio.h (header file).
Printf in Assembly To call printf from assembly language, you just pass the format string in rdi as usual for the first argument, pass any format specifier arguments in the next argument register rsi, then rdx, etc.
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.
This code:
printf("%s%s", printStr1("foo"), printStr2("bar"));
is equivalent to this:
const char *p1 = printStr1("foo");
const char *p2 = printStr2("bar");
printf("%s%s", p1, p2);
or this (depending on the compiler):
const char *p2 = printStr2("bar");
const char *p1 = printStr1("foo");
printf("%s%s", p1, p2);
Now it should be clear why you're getting the output you get.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With