I/O - printf.c

The printf() library function is unimplemented in the current version of the library sets in the ANSI libraries, but is implemented in the terminal.c file. This was done because often no terminal is available or the terminal highly dependent on user hardware.

The ANSI library contains several functions which simplify printf() function implementation, with all its special cases.

Using the first, ANSI-compliant way, allocate a buffer and then use the vsprintf() ANSI function (refer the following listing) .

Listing: Implementation of the printf() Function
int printf(const char *format, ...) {
  char outbuf[MAXLINE];

  int i;

  va_list args;

  va_start(args, format);

  i = vsprintf(outbuf, format, args);

  va_end(args);

  WriteString(outbuf);

  return i;

}

The value of MAXLINE defines the maximum size of any value of printf(). Assume the WriteString() function writes one string to a terminal. The disadvantages of this solution include:

Therefore we do not recommend this solution. Newer library version provide two non-ANSI functions (vprintf() and set_printf()) to avoid both disadvantages. Because these functions are non-ANSI extensions, they are not contained in the stdio.h header file. Therefore, specify their prototypes before using. Refer the following listing.

Listing: Prototypes of vprintf() and set_printf()
int vprintf(const char *pformat, va_list args);
void set_printf(void (*f)(char));

The set_printf() function installs a callback function, which is called later for every character vprintf() prints.

Be advised that calls to set_printf() and vprintf() also implement the standard ANSI C printf() derivatives functions sprintf() and vsprintf(). This allows code sharing across all printf derivatives.

There is one limitation of the printf() implementation. Because the callback function is not passed as an argument to vprintf(), but held in a global variable, none of the printf() derivatives are reentrant. Calls to different derivatives at the same time are not allowed.

The following listing shows a simple implementation of a printf() with vprintf() and set_printf().

Listing: Implementation of printf() with vprintf() and set_printf()
int printf(const char *format, ...){
  int i;

  va_list args;

  set_printf(PutChar);

  va_start(args, format);

  i = vprintf(format, args);

  va_end(args);

  return i;

}

Assume the PutChar() function prints one character to the terminal.

Another remark must be made about the printf() and scanf() functions. printf.c provides the full source code of all printf() derivatives and scanf.c provides the full source code of all scanf() derivatives. Specific applications usually do not use many of the features of printf() and scanf(). The source code of the printf and scanf library modules contains switches (defines) to allow the user to switch off unused parts of the code. This includes the large floating-point portions of vprintf() and vsscanf().