Is there a general-purpose printf-ish routine defined in any C standard
In many C libraries, there is a printf-style routine which is something like the following:
int __vgprintf(void *info, (void)(*print_function(void*, char)), const char *format, va_list params);
which will format the supplied string and call print_function with the passed-in info value and each character in sequence. A function like fprintf will pass __vgprintf the passed-in file parameter and a pointer to a function which will cast its void* to a FILE* and output the passed-in character to that file. A function like snprintf will create a struct holding a char* and length, and pass the address of that struct to a function which will output each character in sequence, space permitting.
Is there any standard for such a function, which could be used if e.g. one wanted a function to output an arbitrary format to a TCP port? A common approach is to allocate a buffer one hopes is big enough, use snprintf to put the data there, and then output the data from the buffer. It would seem cleaner, though, if t开发者_StackOverflowhere were a standard way to to specify that the print formatter should call a user-supplied routine with each character.
Is there any standard for such a function, which could be used if e.g. one wanted a function to output an arbitrary format to a TCP port?
You can wrap a file descriptor or a socket into FILE*
using fdopen()
and pass it into fprintf()
. However, this does not work with non-blocking sockets.
Formatting in a buffer first gives you much greater flexibility and the ability to use it with non-blocking sockets.
open_memstream
is standard in POSIX, and might be standardized as part of the C language in the upcoming C1x standard. However this does not offer you an arbitrary callback; it requires that the whole output fit into memory, so it's really not any better than using snprintf
(possibly wrapped by a function that automatically allocates a buffer).
On POSIX systems, one solution is to make a pipe to a new thread, and then use dprintf
(or fdopen
and fprintf
) to write to it. The thread will receive the input on the other end of the pipe and can process it however it likes. Of course this is mildly slow (at least a couple syscalls every time output is flushed, and possibly a context switch if you have too few cores available) but it does what you want. The same approach will work on any system with pipes, threads, and the equivalent of fdopen
or dprintf
, so you should be able to make it work on Windows too if needed.
Another approach is to use tmpfile
, fprintf
, and fread
(all standard C). A good implementation of tmpfile
could even create a virtual file in memory, and postpone any actual file creation until fileno
is called or the "file" size exceeds a certain limit.
Edit: Upon rereading the question, it seems OP just needs to use fprintf
with sockets. In that case, fdopen
/fprintf
or dprintf
accomplishes the task directly.
Nonstandard, but take a look at fopencookie
on Linux and funopen
on BSD. It might be possible to have wrap them in a standard API from your application, since they're very similar. I believe that Cygwin and Mac OS X support at least one of the two as well.
Both functions allow you to create a FILE *
with function pointers for reading, writing, seeking, and closing the stream. Once created, you can fprintf
into the stream.
I seriously doubt there is such a standard function, but you can of course create your own implementation to try and mimic it. Sorry.
精彩评论