PRINT(2) PRINT(2)
NAME
print, fprint, sprint, snprint, seprint, fmtinstall,
strconv, Strconv, numbconv, fltconv, doprint - print
formatted output
SYNOPSIS
#include <u.h>
#include <libc.h>
int print(char *format, ...)
int fprint(int fd, char *format, ...)
int sprint(char *s, char *format, ...)
int snprint(char *s, int len, char *format, ...)
char* seprint(char *s, char *e, char *format, ...)
int fmtinstall(int c, int (*f)(va_list*, Fconv*))
void strconv(char *s, Fconv *fp)
void Strconv(Rune *s, Fconv *fp)
int numbconv(va_list *arg, Fconv *fp)
int fltconv(va_list *arg, Fconv *fp)
char* doprint(char *s, char *es, char *format, va_list arg)
extern int printcol;
DESCRIPTION
Print writes text to the standard output. Fprint writes to
the named output file descriptor; a buffered form is
described in bio(2). Sprint places text followed by the NUL
character (\0) in consecutive bytes starting at s; it is the
user's responsibility to ensure that enough storage is
available. Each function returns the number of bytes trans-
mitted (not including the NUL in the case of sprint), or a
negative value if an output error was encountered.
Snprint is like sprint, but will not place more than len
bytes in s. Its result is always NUL-terminated and holds
the maximal number of complete UTF-8 characters that can
fit. Seprint is like snprint, except that the end is indi-
cated by a pointer e rather than a count and the return
value points to the terminating NUL of the resulting string.
Page 1 Plan 9 (printed 10/21/25)
PRINT(2) PRINT(2)
Each of these functions converts, formats, and prints its
trailing arguments under control of a format string. The
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 is ignored.
Each conversion specification has the following format:
% [flags] verb
The verb is a single character and each flag is a single
character or a (decimal) numeric string. Up to two numeric
strings may be used; the first is called f1, the second f2.
A period can be used to separate them, and if the period is
present then f1 and f2 are taken to be zero if missing, oth-
erwise they are `omitted'. Either or both of the numbers
may be replaced with the character *, meaning that the
actual number will be obtained from the argument list as an
integer. The flags and numbers are arguments to the verb
described below.
The numeric verbs d, o, x, and X format their arguments in
decimal, octal, hexadecimal, and upper case hexadecimal.
Each interprets the flags h, l, u, +, -, and # to mean
short, long, unsigned, always print a sign, left justified,
and alternate format. If neither short nor long is speci-
fied, then the argument is an int. If unsigned is speci-
fied, then the argument is interpreted as a positive number
and no sign is output. If two l flags are given, then the
argument is interpreted as a vlong (a 4-byte or sometimes
8-byte integer). If f2 is not omitted, the number is padded
on the left with zeros until at least f2 digits appear.
Then, if alternate format is specified, for o conversion,
the number is preceded by a 0 if it doesn't already begin
with one; for x conversion, the number is preceded by 0x;
for X conversion, the number is preceded by 0X. Finally, if
f1 is not omitted, the number is padded on the left (or
right, if left justification is specified) with enough
blanks to make the field at least f1 characters long.
The floating point verbs f, e, E, g, and G take a double
argument. Each interprets the flags +, -, and # to mean
always print a sign, left justified, and alternate format.
F1 is the minimum field width and, if the converted value
takes up less than f1 characters, it is padded on the left
(or right, if `left justified') with spaces. F2 is the num-
ber of digits that are converted after the decimal place for
e, E, and f conversions, and f2 is the maximum number of
Page 2 Plan 9 (printed 10/21/25)
PRINT(2) PRINT(2)
significant digits for g and G conversions. The f verb pro-
duces output of the form [-]digits[.digits]. E conversion
appends an exponent E[-]digits, and e conversion appends an
exponent e[-]digits. The g verb will output the argument in
either e or f with the goal of producing the smallest out-
put. Also, trailing zeros are omitted from the fraction
part of the output, and a trailing decimal point appears
only if it is followed by a digit. The G verb is similar,
but uses E format instead of e. When alternate format is
specified, the result will always contain a decimal point,
and for g and G conversions, trailing zeros are not removed.
The s verb copies a string (pointer to char) to the output.
The number of characters copied (n) is the minimum of the
size of the string and f2. These n characters are justified
within a field of f1 characters as described above. The S
verb is similar, but it interprets its pointer as an array
of runes (see utf(6)); the runes are converted to UTF before
output.
The c verb copies a single char (promoted to int) justified
within a field of f1 characters as described above. The C
verb is similar, but works on runes.
The p verb formats a pointer value. At the moment, it is a
synonym for ux, but that will change once pointers and inte-
gers are different sizes.
The r verb takes no arguments; it copies the error string
returned by a call to errstr(2).
Fmtinstall is used to install custom verbs and flags labeled
by character c, which must have value less than 512. Fn
should be declared as
int fn(va_list *arg, Fconv *fp)
Fp->chr is the flag or verb character to cause fn to be
called. In fn, fp->f1 and fp->f2 are the decoded flags in
the conversion. A missing fp->f1 is denoted by the value
zero. A missing fp->f2 is denoted by a negative number.
Fp->f3 is the bitwise OR of all the flags seen since the
most recent `%'. The standard flags values are: 1 (+), 2
(-), 4 (#), 8 (l), 16 (h), 32 (u), and 64 (ll). Fn is
passed a pointer arg to the argument list. If fp->chr is a
verb, fn should use va_arg to fetch its argument from the
list, then format it, and return zero. If fp->chr is a
flag, fn should return a negative value: the negation of one
of the above flag values, or some otherwise unused power of
two. All interpretation of fp->f1, fp->f2, and fp->f3 is
left up to the conversion routine. Fmtinstall returns 0 if
the installation succeeds, -1 if it fails.
Page 3 Plan 9 (printed 10/21/25)
PRINT(2) PRINT(2)
Sprint, snprint, and seprint are re-entrant; they may be
called to help prepare output in custom conversion routines.
The function strconv formats a UTF string. S is the string,
fp has the same meaning as above. The strconv routine
interprets the `-' flag in fp->f3 as left-justification.
The function Strconv (with a capital S) is like strconv, but
its input is a rune string, which is converted to UTF on
output.
Printcol indicates the position of the next output charac-
ter. Tabs, backspaces and carriage returns are interpreted
appropriately.
Numbconv and fltconv are used to implement the integer and
floating verbs. Their arguments are like those of the func-
tion argument to fmtinstall. Both numbconv and fltconv use
strconv to put their results into the current print buffer.
One of strconv or Strconv must be called to produce output;
no other routine puts characters in the output buffer.
Doprint formats the argument list arg arg into the buffer
starting at s, but it writes no characters after the address
es. It returns a pointer to the NUL terminating the format-
ted string.
EXAMPLES
This function prints an error message with a variable number
of arguments and then quits.
void fatal(char *msg, ...)
{
char buf[1024], *out;
va_list arg;
out = doprint(buf, buf+sizeof(buf), "Fatal error: ");
va_start(arg, msg);
out = doprint(out, buf+sizeof(buf), msg, arg);
va_end(arg);
write(2, buf, out-buf);
exits("fatal error");
}
This example adds a verb to print complex numbers.
typedef
struct {
double r, i;
} Complex;
int
Page 4 Plan 9 (printed 10/21/25)
PRINT(2) PRINT(2)
Xconv(va_list *arg, Fconv *fp)
{
char str[50];
Complex c;
c = va_arg(*arg, Complex);
sprint(str, "(%g,%g)", c.r, c.i);
strconv(str, fp);
return 0;
}
main(...)
{
Complex x = (Complex){ 1.5, -2.3 };
fmtinstall('X', Xconv);
print("x = %X\n", x);
}
SOURCE
/sys/src/libc/port
SEE ALSO
fprintf(2), utf(6), errstr(2)
DIAGNOSTICS
Print and fprint set errstr.
BUGS
The formatting is close to that specified for ANSI
fprintf(2); the differences are:
the - flag doesn't work
u is a flag here instead of a verb
there are no 0 or space flags here
there are no P or n verbs here
Also, and distinctly not a bug, print and friends generate
UTF rather than ASCII.
Page 5 Plan 9 (printed 10/21/25)