开发者

A combined function for fprintf and write in c/c++

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 of printf(), perhaps with a prototype like

void dprintf (int level, const char *format, ...);

where the first parameter is a debugging level (and output is to stderr). Moreover, dprintf() (or DPRINTF) is also a popular macro name for a debugging printf. 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;
}

`

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜