Reputation: 14583
I've got a program that takes a format string from the command line which represents the format for the filenames of multiple output files. It should take just a single integer argument that can be substituted in to generate the real output filenames, and I'd like to verify that when doing my input checking. What's a good way to determine the number of arguments a format string expects in C?
Upvotes: 1
Views: 1153
Reputation: 316
The GNU C library contains a function parse_printf_format
that can be used in your case. From the glibc manual, section 12.12.10 - Parsing a template string:
You can use the function parse_printf_format to obtain information about the number and types of arguments that are expected by a given template string. This function permits interpreters that provide interfaces to printf to avoid passing along invalid arguments from the user’s program, which could cause a crash.
parse_printf_format returns the total number of arguments required by template. If this number is greater than n, then the information returned describes only the first n arguments. If you want information about additional arguments, allocate a bigger array and call parse_printf_format again.
Usecase example:
#include <printf.h>
size_t arguments_count = parse_printf_format ("Your discount: %d%%\n", 0, NULL);
/* arguments_count now holds a value of 1 */
Upvotes: 1
Reputation: 157394
The number of arguments accepted depends on the version of your C library (for example, %a
conversion specifiers were added in C99). You can be certain that it is no greater than the number of unescaped %
characters (i.e., the number of %
characters remaining after all %%
sequences are removed) plus the number of *
characters (which could be width specifiers).
You should consider security issues, though; if the user supplies a %n
format specifier this could result in a write to an arbitrary memory location. In other cases, supplying e.g. %f
would result in garbage values being output, %s
in arbitrary memory contents, and even with %d
specifiers allowing the user to supply a field width e.g. %255d
could result in buffer overflow. It would be smarter to consider a different formatting scheme e.g. replacing a token (which could still be %d
), but not allowing the user to supply a printf
format string.
Upvotes: 1