mcPrint, mcVPrint, mcSPrint, mcVSPrint — Safe and Portable Formatted Output Conversion
#include <memcom.h>
int mcPrint(FILE* out, const char* fmt, ...);
int mcVPrint(FILE* out, const char* fmt, va_list ap);
int mcSPrint(char* buffer, mcSize bufsize, const char* fmt, ...);
int mcVSPrint(char* buffer, mcSize bufsize, const char* fmt,
              va_list ap);mcPrint, mcVPrint, mcSPrint, and mcVSPrint take a format string
          and a variable number of arguments, either convert them into a
          string and dump this string to a file stream
          (mcPrint and mcVPrint), or
          convert them directly in a user-supplied buffer
          (mcSPrint and
          mcSVPrint).
outStdio stream which is writable, such as
                  stdout or stderr. See
                  stdio (3) for more information on how
                  to create and use streams.
bufferBuffer provided by the caller. The size of the buffer
                  must be equal to bufsize. The formatted
                  string will be copied into this buffer.
bufsizeThe size of the buffer. This argument is important to
                  avoid buffer overflows, an error condition which happens
                  frequently when using the (deprecated)
                  sprintf (3) function
                  call.
fmtThe format string. It is composed of zero or more
                  directives and ordinary characters (not '%'). The ordinary
                  characters are unchanged while the directives specify the
                  conversions to be applied to the arguments supplied
                  after the fmt
                  argument. The functions support all directives which are
                  supported by fprintf in addition, the
                  following directives are supported: 
OThe next argument is of type
                          mcOff.
UThe next argument is of type
                          mcSize.
These functions return the number of characters of the
          converted string, not including the trailing 0 character used to
          terminate the string. The mcSPrint and
          mcSVPrint never write past the end of the
          supplied buffer and always terminate the string with a trailing 0
          character.
To test if the buffer is too small and the string had thus to be truncated, use:
char buf[10];
if (mcSPrint(buf, sizeof(buf), "This is a test") >= sizeof(buf)) {
    mcPrint(stderr, "buffer too small (%s)!\n", buf);
    ...
}The functions mcVPrint and
          mcVSPrint can be called from
          within functions that take a variable number of
          arguments:
void
my_log(const char* fmt, ...)
{
    va_list ap;
    mcPrint(stderr, "log entry: ");
    va_start(ap, fmt);
    mcVPrint(stderr, fmt, ap);
    va_end(ap);
}To print the offset of a dataset:
mcSetAttributes att;
if (mcDBinqSetAtt(handle, dsname, &att) != 1)
    mcPrint(stderr, "dataset %s does not exist!\n", dsname);
else {
    mcPrint(stdout, "file offset for dataset %s: %O\n", dsname, att.faddr);
    mcPrint(stdout, "descriptor size for %s: %U\n", dsname, att.dsize);
}