vonludi
vonludi

Reputation: 429

How does fprintf format arguments?

I am currently trying to pass an arbitrary number of parameters of MyType to fprintf like this:

void myPrint(const char* fmt, std::initializer_list<MyType> args)
{
  fprintf(stdout, fmt, args);
}

where MyType is basically a variant and can be constructed from most common types (int, string, uint*, bool, ...). Now when calling myPrint(...) like this

myPrint("I am a hex int: %x", { 5 } );

this will always print the address of the initializer_list. When looking at the references, e.g. cplusplus.com, it says

[...] If format includes format specifiers (subsequences beginning with %), the additional arguments following format are formatted and inserted in the resulting string replacing their respective specifiers. [...]

or microsoft.com

[...] Each function argument (if any) is converted and output according to the corresponding format specification in format. [...]

So, my question is: How does fprintf format or convert its arguments? Does it use operators? Does it use casts?

Upvotes: 3

Views: 749

Answers (1)

MSalters
MSalters

Reputation: 179917

fprintf is a function inherited from C. In particular, it takes a C variadic argument: int fprintf(FILE*, const char*, ...).

You can only pass built-in C types to such a function, not even user-defined C types. Attempting to do so is Undefined Behavior. Trying to pass a MyType is dangerous (e.g. the string you mention is not allowed). Passing a std::initializer_list<T> is always Undefined Behavior.

As Jarod states in the comments, use std::cout <<. If you need fancier formatting, use Boost.format.

Upvotes: 2

Related Questions