printf#
Write a formatted string to a filehandle.
printf is print FILEHANDLE sprintf(FORMAT, LIST) with one
deliberate exception: the output record separator $\ is not
appended. The targeting rules are otherwise the print rules —
bareword or simple-scalar filehandle immediately before the argument
list, or the {EXPR} block form for anything more complex. If
FILEHANDLE is omitted, output goes to the currently selected handle
(see select), which starts life as STDOUT.
See sprintf for the format-specifier reference —
everything %d, %s, %.3f, %*d, %1$s, %v, vector flags,
locale-sensitive %f, and so on. This page covers only the
printf-specific surface: filehandle resolution, the format-is-first
rule, and the quirks around the no-argument form.
Synopsis#
printf FORMAT, LIST
printf FILEHANDLE FORMAT, LIST
printf {EXPR} FORMAT, LIST
printf FH # bareword filehandle, $_ as format
What you get back#
1 on success, undef on failure (with $! set). As with
print, the return value is rarely checked for writes to
STDOUT / STDERR, and worth checking for writes to files, pipes,
and sockets where partial writes and broken pipes matter.
printf $fh "%-20s %8d\n", $name, $count
or die "write to $path failed: $!";
Global state it touches#
Selected filehandle (changed via
select): the destination whenFILEHANDLEis omitted. Starts asSTDOUT.$\(output record separator): deliberately not appended — this is the one semantic difference betweenprintf FORMAT, LISTandprint FILEHANDLE sprintf(FORMAT, LIST). Put the newline in the format string.$,(output field separator): not consulted.printfsplices list elements into the format according to the conversions, not with a separator.$_: used as the format when bothFORMATandLISTare omitted, not appended to output. Almost never what you want; see Edge cases.$!: set on write failure.$|: autoflush flag for the selected handle.printfbuffers through PerlIO likeprint.LC_NUMERIClocale: whenuse localeis active andPOSIX::setlocalehas been called, the decimal separator for floating-point conversions (%f,%e,%g) follows the locale.
Examples#
Basic formatted write to STDOUT. Unlike say or
print-with-$\, the trailing newline is on you:
printf "%s is %d years old\n", $name, $age;
Width and precision for a tidy column:
printf "%-20s %8.2f\n", $item, $price;
Write to a filehandle. Bareword and simple scalar work directly; no comma between the filehandle and the format:
open my $fh, ">", "report.txt" or die $!;
printf $fh "%5d %s\n", $n, $msg;
close $fh;
Filehandle held in a more complex expression — use the {EXPR}
block form (same rule as print):
my @logs = (\*STDOUT, \*STDERR);
printf { $logs[$severity] } "[%s] %s\n", $tag, $msg;
Repeated format with a list that spans multiple records. printf
does not re-apply the format per record — conversions are
consumed once, left to right:
printf "%s=%s\n", "user", "alice"; # "user=alice\n"
printf "%s=%s\n%s=%s\n", # two records, one call
"user", "alice", "host", "db1";
Locale-sensitive decimal separator:
use POSIX qw(setlocale LC_NUMERIC);
use locale;
setlocale(LC_NUMERIC, "de_DE.UTF-8");
printf "%.2f\n", 1234.5; # "1234,50\n"
Edge cases#
No
LISTgiven,$_becomes the format.printf;andprintf FH;(bareword filehandle) format$_. If$_contains any%conversions they expand against an empty argument list — each%s/%dbecomes the empty string anduse warningsemits aMissing argument in printfwarning. To write$_verbatim useprint, notprintf.Indirect filehandle without a list is ambiguous and not supported.
printf $fh;parses$fhas the format, not the filehandle. If you need a no-argument form with a scalar filehandle, go throughprintor pass an explicit format:printf $fh "%s", $_.The first argument is always the format.
printf(@_)uses$_[0]as the format and the remaining elements as arguments — this is a parsing rule, not a convention. Build the format deliberately; don’t splat user-supplied lists intoprintfunless the first element is known-safe.No
$\is appended. Embedding"\n"in the format is the idiomatic terminator. Settinglocal $\ = "\n"has no effect onprintfoutput.$,is ignored. The output field separator is aprintconcept;printfjoins nothing — it substitutes.printf (…)parses as a function call, just likeprint.printf ("%d", 1)*2computesprintf(...)then multiplies the return value by2and discards it. Wrap the whole argument list in parens or prefix with+if you need to disambiguate.Closed filehandle: returns
undefand sets$!to"Bad file descriptor". Underuse warningsaprintf() on closed filehandlewarning is emitted.Encoding layers:
printfwrites through the handle’s PerlIO stack. A:utf8or:encoding(...)layer encodes on the way out; a bytes-mode handle with a wide-character string emitsWide character in printfand writes raw codepoints.SIGPIPEon closed pipe/socket: default action terminates the process. Install$SIG{PIPE}to turn it into a checkable write failure.Don’t use
printfwhereprintsuffices.printf "%s", $msgis slower and more error-prone thanprint $msg— the format string is parsed on every call, and a stray%in$msgused as a format becomes a bug waiting to happen.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
print— unformatted write with the same filehandle rules; faster, and appends$\whereprintfdoes notsprintf— build the formatted string without writing it; the format-specifier reference lives heresay—printwith$\forced to"\n"; reach for it when every record ends in a newlineselect— change which filehandle the no-filehandle form ofprintfwrites to$\— output record separator; deliberately not appended byprintf$_— used as the format when bothFORMATandLISTare omitted