|
|
researchv10 Dan Cross
.TH PRINT 3
.CT 2 file_io
.SH NAME
print, fprint, sprint, fmtinstall \(mi print formatted output
.SH SYNOPSIS
.nf
.BR "int print(format \fR[\fP , arg \fR]\fP ... )"
.B char \(**format;
.PP
.BR "int fprint(fildes, format \fR[\fP , arg \fR]\fP ... )"
.B int fildes;
.B char \(**format;
.PP
.BR "int sprint(s, format \fR[\fP , arg \fR]\fP ... )"
.B char \(**s, \(**format;
.PP
.B fmtinstall(c, fn)
.B char c;
.B int (*fn)();
.PP
.B strconv(s, f1, f2)
.B char *s;
.PP
.B extern int printcol;
.fi
.SH DESCRIPTION
.I Print
places output on the standard output.
.I Fprint
places output on the named output
file descriptor;
a buffered form
is described in
.IR fio (3).
.I Sprint
places output
followed by the null character
.RB ( \e0 )
in consecutive bytes starting at
.IR s ;
it is the user's responsibility to ensure that
enough storage is available.
Each function returns the number of characters
transmitted (not including the
.B \e0
in the case of
.IR sprint ),
or
a negative value if an output error was encountered.
.PP
Each of these functions
converts, formats, and prints its
trailing arguments
under control of a
.IR format
string.
The
.I format
contains two types of objects:
plain characters, which are simply copied to the
output stream,
and conversion specifications,
each of which results in fetching of
zero or more
arguments.
The results are undefined if there are arguments of the
wrong type or too few
arguments for the format.
If the format is exhausted while
arguments remain, the excess
are ignored.
.PP
Each conversion specification has the following format
.PP
.B "% [flags] [[\(mi] digits [. digits]] verb
.PP
The
.I flags
modify the meaning of
the conversion verb.
The first (possibly negative) number is called
.IR f1 ,
the second number is
.IR f2 .
The flags and numbers are arguments to
the
.I verb
described below.
.PP
The numeric verbs
.BR d ,
.BR o ,
and
.B x
format their arguments in decimal,
octal and hex respectively.
Each interprets the flags
.BR h ,
.BR l ,
.BR u ,
to mean short,
long,
and unsigned.
If neither
short nor long is specified,
then the arg is an
.BR int .
If unsigned is specified,
then the arg is interpreted as a
positive number and no sign is output.
.I F1
is the minimum field width and,
if negative,
means left justified rather than right justified;
in both cases, padding is done with blanks.
The converted number is padded with
.B 0
on the left to at least
.I f2
characters.
.PP
The floating point verbs
.BR f ,
.BR e ,
and
.B g
take a double argument.
No flags apply to floating point conversions.
.I F1
is the minimum field width and,
if negative,
means left justified.
.I F2
is the number of digits that are converted after the decimal place.
The first unconverted digit has suffered decimal rounding.
The
.B f
verb produces output of the form
.RB [ - ] digits [ .digits\fR].
.B e
conversion appends an exponent
.BR e [ - ] digits .
The
.B g
verb will output the arg in either
.B e
or
.B f
with the goal of producing the smallest output.
.PP
The
.B s
verb copies a string
(pointer to character)
to the output.
The number of characters copied
.RI ( n )
is the minimum
of the size of the string and
.IR f2 .
These
.I n
characters are justified within a field of
.I f1
characters as described above.
.PP
The
.B c
verb copies a single character (int)
justified within a field of
.I f1
characters as described above.
.PP
.I Fmtinstall
is used to install your own conversions and flags.
.I Fn
should be declared as
.EX
int fn(o, f1, f2, f3)
void *o;
int f1, f2, f3;
.EE
.I Fn
is passed a pointer
.I o
to whatever argument appears in
the list to
.IR print .
.I Fn
should return the size of the argument in bytes so
.I print
can skip over it.
.I F1
and
.I f2
are the decoded numbers in the conversion.
A missing
.I f1
is denoted by the value zero.
A missing
.I f2
is denoted by a negative number.
.I F3
is the logical or of all the
flags seen in the conversion.
If
.I c
is a flag,
.I fn
should return a negative number
that is negated and then logically
.IR or ed
with any other flags
and ultimately
passed to a conversion routine.
All interpretation of
.IR f1 ,
.IR f2 ,
and
.I f3
is left up to the conversion routine.
The standard flags are
.LR h (2),
.LR l (1),
and
.LR u (4).
.PP
.I Sprint
is designed to be recursive in order to
help prepare output in custom conversion routines.
.PP
The output of any conversion routine must be passed through
.IR strconv .
.I S
is the character string,
.I f1
and
.I f2
have the same meaning as above.
.PP
.I Printcol
indicates the position of the next output character.
Tabs, backspaces and carriage returns are interpreted appropriately.
.SH EXAMPLES
This adds a verb to print complex numbers.
.EX
typedef struct {
double r, i;
} complex;
complex x = { 1.5, -2.3 };
int Xconv();
main()
{
fmtinstall('X', Xconv);
print("x = %X\en", x);
}
Xconv(o, f1, f2, f3)
complex *o;
{
char str[50];
sprint(str, "(%g,%g)", o->r, o->i);
strconv(str, f1, f2);
return(sizeof(complex));
}
.EE
.SH SEE ALSO
.IR fio (3),
.IR printf (3)
.SH BUGS
There are internal buffers which may overflow silently.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.