I've always felt that the 'right' solution was to emulate glibc and provide facilities for registering new format specifiers. Then libraries could provide specifiers for everything that made sense and users could pick and choose.
Of course, there would be performance implications - not to mention the added complexity for implementors.
The simplest solution (from the implementor's perspective) is probably to leave it to the user to reassign one. Allowing multiple-letter specifiers helps here. Coming from a C perspective, that's what I would prefer.
You could work out all sorts of namespacing and automatic reassignment schemes, of course.
I can't think of anything without trade-offs off the top of my head (I double that anything exists), but in my (limited) experience it's very workable.