In C/C++, there is a 'write() function which let me write to either file or a socket, I just pass in the file descriptor accordingly). And there is a fprintf() which allow me to do fprintf (myFile, "hello %d", name); but it only works for file.
Is th开发者_如何学运维ere any api which allows me to do both? i.e. able to let me do print formatting and able to switch between writing to file or socket?
Thank you.
Sure: just use fdopen
on the socket to create a FILE*
stream, and use fprintf
appropriately.
In C, on POSIX-ish machines (which you must have to be using 'write()'), you can use:
fdopen()
to create a file stream from a file descriptor.fileno()
to obtain a file descriptor from a file stream.
You need to be careful about flushing the file stream at appropriate times before using the matching file descriptor.
You can use sprintf
or snprintf
to print to a char *
buffer, and then use write
. To get a file descriptor from a FILE *
variable, you can use fileno
. There is no portable way to go from a file descriptor to a FILE *
, though: you can portably to use fdopen
to associate a FILE *
with a valid file descriptor.
In addition, the latest POSIX standard specifies dprintf
, but the GNU libc dprintf
man page has this to say:
These functions are GNU extensions, not in C or POSIX. Clearly, the names were badly chosen. Many systems (like MacOS) have incompatible functions called
dprintf()
, usually some debugging version ofprintf()
, perhaps with a prototype likevoid dprintf (int level, const char *format, ...);
where the first parameter is a debugging level (and output is to
stderr
). Moreover,dprintf()
(orDPRINTF
) is also a popular macro name for a debuggingprintf
. So, probably, it is better to avoid this function in programs intended to be portable.
Of course, the libc manual page is not updated with the latest standard in mind, but you still have to be careful with using dprintf
, since you might get something you don't want. :-)
You can do something like this, maybe :
#include <stdarg.h>
int fdprintf(int fd, const char* fmt, ...) {
char buffer[4096] = {0};
int cc;
va_list args;
va_start(args, fmt);
if ((cc = vsnprintf(buffer, 4096, fmt, args)) > 0) {
write(fd, buffer, cc);
}
va_end(args);
return cc;
}
generalizing tusbar answer, and to make it work with visual studio you can try the following codes: `
int fdprintf(int fd, const char* fmt, ...) {
int cc;
va_list args;
va_start(args, fmt);
int len = _vscprintf(fmt,args) + 1;
char* buffer = new char[len];
buffer[len] = 0;
if ((cc = vsprintf_s(buffer, len-1, fmt, args)) > 0) {
write(fd, buffer, cc);
}
va_end(args);
delete[] buffer;
return cc;
}
`
精彩评论