printf string, variable length item
Solution 1
There is no need to construct a special format string. printf
allows you to specify the precision using a parameter (that precedes the value) if you use a .*
as the precision in the format tag.
For example:
printf ("%d %.*s", number, SIZE, letters);
Note: there is a distinction between width (which is a minimum field width) and precision (which gives the maximum number of characters to be printed).
%*s
specifies the width, %.s
specifies the precision. (and you can also use %*.*
but then you need two parameters, one for the width one for the precision)
See also the printf man page (man 3 printf
under Linux) and especially the sections on field width and precision:
Instead of a decimal digit string one may write "*" or "*m$" (for some decimal integer m) to specify that the precision is given in the next argument, or in the m-th argument, respectively, which must be of type int.
Solution 2
A somewhat unknown function is asprintf
. The first parameter is a **char
. This function will malloc
space for the string so you don't have to do the bookkeeping. Remember to free
the string when done.
char *fmt_string;
asprintf(&fmt_string, "%%d %%%ds", SIZE);
printf(fmt_string, number, letters);
free(fmt_string);
is an example of use.
William Entriken
Lead author of ERC-721. Personal website and contact information: https://phor.net Promoting two open source projects: https://github.com/fulldecent/web-puc - A script to validate you are using the latest JQuery, Bootstrap, Font Awesome versions in your favorite PHP or other web front-end (compatible with Travis CI) https://fulldecent.github.io/cameralife/ - Mature LAMP project for displaying large photo collections on the web (i.e. your life work)
Updated on July 09, 2022Comments
-
William Entriken almost 2 years
#define SIZE 9 int number=5; char letters[SIZE]; /* this wont be null-terminated */ ... char fmt_string[20]; sprintf(fmt_string, "%%d %%%ds", SIZE); /* fmt_string = "%d %9d"... or it should be */ printf(fmt_string, number, letters);
Is there a better way to do this?
-
Trent about 13 yearsAlthough asprintf is indeed an interesting function, it is important to note that it is a gnu extention. Also, I'm not sure how this addresses the question.
-
William Entriken almost 13 yearsHad them mixed up... scanf is the one that doesn't have that option.
-
ott-- over 10 yearsIt also works with 2 lengths like
"%*.*s", minlength, maxlength, letters
. -
Cristian Ciupitu over 9 years
-
chux - Reinstate Monica about 8 yearsNote:
"*m$"
is not standard C. -
Jimmay almost 8 yearsIs there a way to get the "%.*s" format to accept
size_t
instead ofint
?