Portable printf extension ?

L

lithiumcat

Hi,

I was wondering whether there is a standard-compliant way to extend
printf with a new %code that is not yet reserved (e.g. %r) with a
given argument type.

My guess would be to write a function that looks like « int
my_printf(const char *fmt, ...); », with a special processing of fmt
to replace the new %code with the correct data, and then hand over the
processed fmt and the remaining arguments to vprintf.

However I don't know much about variable arguments, but the standards
seems pretty light about what can be done with them. So I have no idea
of how to write such a my_printf function.

Is there a protable way to do this within the C? If anybody knows,
although it's a bit off-topic, would POSIX allow it if standard C
doesn't? (btw, what is the topical newsgroup for such POSIX-related
questions?)

On a side note, although I'm interested in the answers to the
questions above for my general knowledge of C, the problem I'm trying
to solve is fprintf-ing and snprintf-ing a non-C string, represented
by a struct containing a char* (that is not zero-terminated) and a
size_t length. So I'm also interested in a solution for that
particular problem. For now I'm using a sequence of fprintf/fwrite/
fprintf/... or snprintf/memcpy/snprintf/... but that looks ugly
(especially with the size checks in the second case).
 
R

Richard Bos

[ Do _not_ snip all context from posts - quote enough material to make
it clear what you are talking about.
No, using Google Broken Groups Beta is _not_ an excuse. ]
If your char array is not null terminated, you will have to use
various formatted input/output function that you are already using.
There isn't a way to extend printf and the thing you are suggesting is
to wrap the call in your own user-defined function.

It is quite possible to output non-null-terminated char arrays using the
Standard printf() only, _if_ you know how many characters you want to
print, _and_ there are enough characters in the array.

Hint: precision specifier.

Richard
 
L

lithiumcat

It is quite possible to output non-null-terminated char arrays using the
Standard printf() only, _if_ you know how many characters you want to
print, _and_ there are enough characters in the array.

Hint: precision specifier.

Thanks a lot for that hint, I had completely forgotten about that
specifier. I did thought about the field width specifier (using a star
to get the width from the argument), but that doesn't do what I need.
I guess I forgot the precision because I have never used it.

So the call would look like that:

char *char_array_without_nul;
size_t char_array_size;
[proper initialization]
printf("Here is the string: \"%.*s\"\n", (int)char_array_size,
char_array_without_nul);

If I understand correctly, the cast is needed because int and size_t
might not have the same size (signedness shouldn't an issue as long as
char_array_size is not too large to fit in an int). Right?
 
R

Richard Bos

So the call would look like that:

char *char_array_without_nul;
size_t char_array_size;
[proper initialization]
printf("Here is the string: \"%.*s\"\n", (int)char_array_size,
char_array_without_nul);

If I understand correctly, the cast is needed because int and size_t
might not have the same size (signedness shouldn't an issue as long as
char_array_size is not too large to fit in an int). Right?

Right.

With the proviso that if char_array_size is not correct, but is in fact
larger than the real size of your array, you invoke undefined behaviour;
so just don't do that. But in that, it is no different from, say,
memcpy(). Also, if there _is_ by chance a nul character in your array,
nothing beyond it gets printed.

Richard
 
K

Keith Thompson

So the call would look like that:

char *char_array_without_nul;
size_t char_array_size;
[proper initialization]
printf("Here is the string: \"%.*s\"\n", (int)char_array_size,
char_array_without_nul);

If I understand correctly, the cast is needed because int and size_t
might not have the same size (signedness shouldn't an issue as long as
char_array_size is not too large to fit in an int). Right?

Right.

With the proviso that if char_array_size is not correct, but is in fact
larger than the real size of your array, you invoke undefined behaviour;
so just don't do that. But in that, it is no different from, say,
memcpy(). Also, if there _is_ by chance a nul character in your array,
nothing beyond it gets printed.

To be precise, neither the nul character nor anything beyond it gets
printed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top