Novice 'C' user needs help

Michael Meissner meissner at osf.org
Tue Feb 13 10:26:29 AEST 1990


In article <1152 at psc90.UUCP> pyr201 at psc90.UUCP (d^2) writes:

| Below is a piece of code used in the recently posted Tetris game.
| On our system, (BSD), this produces crap.  Namely the last text
| output is kept forever in some buffer somewhere and it shows up
| in the integer output, ie, 15Press any key.
| 
| I made some hacks to it, but I need to know what the library function
| _doprnt does or better yet what this function form() does.
| 
| Can anyone answer this question for me?  Thanks in advance.
| 
| char *form (va_alist)
|   va_dcl
| {
|   va_list pvar;
|   char *fmt_string;
|   static char result[LINELEN];
|   FILE b;
|   
|   va_start (pvar);
|   fmt_string = va_arg (pvar, char*);
| 
|   b._flag = _IOWRT|_IOSTRG;
|   b._ptr = result;
|   b._cnt = LINELEN;
| 
| --->  _doprnt(fmt_string, pvar, &b); <---
| 
|   putc('\0', &b);
| 
|   va_end (pvar);
|   return (result);
| }

The above function basically does sprintf into a static buffer, and
returns the result.  It sets up the FILE structure in theory so that
any excess output will be thrown away, rather than writing randomly
past the end of the static array.  There is unfortunately no portable
means of doing this.  Some people suggested 'snprintf', which would be
like sprintf, except it would take an extra argument, specifing the
buffer size, but the ANSI standard rejected the proposal.  One way to
deal with this, is to declare a real large buffer, use vsprintf, and
hope for the best.  Another is to write your own printf clone.  If you
have vsprintf, the above function would be written:

char *form (va_va_alist)
  va_dcl
{
  va_list pvar;
  char *fmt_string;
  static char result[BIG_LINELEN];

  va_start (pvar);
  fmt_string = va_arg (pvar, char *);
  vsprintf (result, fmt_string, pvar);
  va_end (pvar);
  return (result);
}


If you have ANSI C, it would be written as follows:

char *form (char *fmt_string, ...)
{
  va_list pvar;
  static char result[BIG_LINELEN];

  va_start (pvar, fmt_string);
  vsprintf (result, fmt_string, pvar);
  va_end (pvar);
  return (result);
}

Note for ANSI C, to be fully legal, a prototype of the form:

extern char *form (char *, ...);

must appear in the scope of any calls to form.

--
Michael Meissner	email: meissner at osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA

Catproof is an oxymoron, Childproof is nearly so



More information about the Comp.unix.wizards mailing list