Learning C at University. This is not a homework, but I was trying to do something (some "creative" part of the assignment) and got stuck.
I understand that this is possible
printf("%d\n", printf("23.4")); // -> 23.44 (i.e. 23.4 + 4 bytes written)
but how can I use sprintf()
as first argument of printf()
?
something like :
char * getFormatString(int n) {
char *开发者_如何学Go buffer;
sprintf(buffer, "Value with %%d decimals is %%.%df", n);
return buffer;
}
void foo() {
int decimals = 2;
float pi = 3.141592;
printf(getFormatString(decimals), decimals, pi); // should output "Value with 2 decimals is 3.14"
}
Is this even possible ? So far, I get a seg fault when executing it.
Using sprintf
for this purpose is perverse. Instead try:
printf("Value with %d decimals is %.*f", decimals, decimals, pi);
You should at least allocate memory for your buffer first (and free it at the end):
char * buffer;
int decimals = 2;
float pi = 3.141592;
buffer = (char *) malloc(256); /* big enough buffer */
sprintf(buffer, "Value with %%d decimals is %%.%df", decimals);
printf(buffer, decimals, pi);
free(buffer);
printf returns the number of characters printed, so your first example would actually be
printf("%d", printf("23.4")); // -> 23.44
sprintf also returns the number of characters printed, so having it be an argument of printf probably isn't what you want.
The reason you're seg-faulting is that your buffer string isn't pointing to anything. You want to change your code to something like this:
char buffer[1024]; // buffer has to be an actual string (or you could use malloc)
int decimals = 2;
float pi = 3.141592;
sprintf(buffer, "Value with %%d decimals is %%.%df", decimals);
printf(buffer, decimals, pi);
You are getting a segfault, because sprintf
writes data to some place in memory which is pointed to by garbage (in the pointer buffer
). You need to allocate some memory using malloc, like:
buffer = malloc(100);
before you use sprintf in function getFormatString
. Then, remember to free this memory after using your string. In this particular code there is a memory leak, because you don't store the pointer returned from getFormatString
anywhere.
Corrected code:
char *getFormatString(int n) {
char *buffer = malloc(100);
sprintf(buffer, "Value with %%d decimals is %%.%df", n);
return buffer;
}
void foo() {
int decimals = 2;
float pi = 3.141592;
char *fmtstr = getFormatString(decimals);
printf(fmtstr, decimals, pi); // should output "Value with 2 decimals is 3.14"
free(fmtstr);
}
printf()
and sprintf()
both return an int
value. Which is the total number of characters.
int sprintf ( char * str, const char * format, ... );
int printf ( const char * format, ... );
You can only use sprintf()
as an argument to printf()
if you are to print the number of characters written by sprintf()
.
精彩评论