--- name: printf signatures: - 'printf FILEHANDLE FORMAT, LIST' - 'printf FILEHANDLE' - 'printf FORMAT, LIST' - 'printf' since: 5.0 status: documented categories: ["I/O"] --- ```{index} single: printf; Perl built-in ``` *[I/O](../perlfunc-by-category)* # printf Write a formatted string to a filehandle. `printf` is `print FILEHANDLE sprintf(FORMAT, LIST)` with one deliberate exception: the output record separator [`$\`](../perlvar) is **not** appended. The targeting rules are otherwise the [`print`](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`](select)), which starts life as `STDOUT`. See [`sprintf`](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 ```perl 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`](undef) on failure (with [`$!`](../perlvar) set). As with [`print`](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. ```perl printf $fh "%-20s %8d\n", $name, $count or die "write to $path failed: $!"; ``` ## Global state it touches - **Selected filehandle** (changed via [`select`](select)): the destination when `FILEHANDLE` is omitted. Starts as `STDOUT`. - [`$\`](../perlvar) (output record separator): deliberately **not** appended — this is the one semantic difference between `printf FORMAT, LIST` and `print FILEHANDLE sprintf(FORMAT, LIST)`. Put the newline in the format string. - [`$,`](../perlvar) (output field separator): **not** consulted. `printf` splices list elements into the format according to the conversions, not with a separator. - [`$_`](../perlvar): used as the **format** when both `FORMAT` and `LIST` are omitted, not appended to output. Almost never what you want; see *Edge cases*. - [`$!`](../perlvar): set on write failure. - [`$|`](../perlvar): autoflush flag for the selected handle. `printf` buffers through PerlIO like [`print`](print). - `LC_NUMERIC` locale: when `use locale` is active and [`POSIX::setlocale`](../../POSIX/setlocale) has been called, the decimal separator for floating-point conversions (`%f`, `%e`, `%g`) follows the locale. ## Examples Basic formatted write to `STDOUT`. Unlike [`say`](say) or [`print`](print)-with-[`$\`](../perlvar), the trailing newline is on you: ```perl printf "%s is %d years old\n", $name, $age; ``` Width and precision for a tidy column: ```perl 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: ```perl 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`](print)): ```perl 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: ```perl 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: ```perl 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 `LIST` given, [`$_`](../perlvar) becomes the format.** `printf;` and `printf FH;` (bareword filehandle) format [`$_`](../perlvar). If [`$_`](../perlvar) contains any `%` conversions they expand against an empty argument list — each `%s` / `%d` becomes the empty string and `use warnings` emits a `Missing argument in printf` warning. To write [`$_`](../perlvar) verbatim use [`print`](print), not `printf`. - **Indirect filehandle without a list is ambiguous** and not supported. `printf $fh;` parses `$fh` as the format, not the filehandle. If you need a no-argument form with a scalar filehandle, go through [`print`](print) or 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 into `printf` unless the first element is known-safe. - **No [`$\`](../perlvar) is appended.** Embedding `"\n"` in the format is the idiomatic terminator. Setting `local $\ = "\n"` has no effect on `printf` output. - **[`$,`](../perlvar) is ignored.** The output field separator is a [`print`](print) concept; `printf` joins nothing — it substitutes. - **`printf (…)` parses as a function call**, just like [`print`](print). `printf ("%d", 1)*2` computes `printf(...)` then multiplies the return value by `2` and discards it. Wrap the whole argument list in parens or prefix with `+` if you need to disambiguate. - **Closed filehandle**: returns [`undef`](undef) and sets [`$!`](../perlvar) to `"Bad file descriptor"`. Under `use warnings` a `printf() on closed filehandle` warning is emitted. - **Encoding layers**: `printf` writes through the handle's PerlIO stack. A `:utf8` or `:encoding(...)` layer encodes on the way out; a bytes-mode handle with a wide-character string emits `Wide character in printf` and writes raw codepoints. - **`SIGPIPE` on closed pipe/socket**: default action terminates the process. Install `$SIG{PIPE}` to turn it into a checkable write failure. - **Don't use `printf` where [`print`](print) suffices.** `printf "%s", $msg` is slower and more error-prone than `print $msg` — the format string is parsed on every call, and a stray `%` in `$msg` used as a format becomes a bug waiting to happen. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`print`](print) — unformatted write with the same filehandle rules; faster, and appends [`$\`](../perlvar) where `printf` does not - [`sprintf`](sprintf) — build the formatted string without writing it; the format-specifier reference lives here - [`say`](say) — [`print`](print) with [`$\`](../perlvar) forced to `"\n"`; reach for it when every record ends in a newline - [`select`](select) — change which filehandle the no-filehandle form of `printf` writes to - [`$\`](../perlvar) — output record separator; deliberately not appended by `printf` - [`$_`](../perlvar) — used as the format when both `FORMAT` and `LIST` are omitted