开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜