4.31 Formatted Write

The current version of SWI-Prolog provides two formatted write predicates. The `writef' family (writef/1, writef/2, swritef/3), is compatible with Edinburgh C-Prolog and should be considered deprecated. The `format' family (format/1, format/2, format/3), was defined by Quintus Prolog and currently available in many Prolog systems, although the details vary.

4.31.1 Writef

[deprecated]writef(+Atom)
Equivalent to writef(Atom, []). See writef/2 for details.
[deprecated]writef(+Format, +Arguments)
Formatted write. Format is an atom whose characters will be printed. Format may contain certain special character sequences which specify certain formatting and substitution actions. Arguments provides all the terms required to be output.

Escape sequences to generate a single special character:

\n Output a newline character (see also nl/[0,1])
\l Output a line separator (same as \n)
\r Output a carriage return character (ASCII 13)
\t Output the ASCII character TAB (9)
\\ The character \ is output
\% The character % is output
\nnn where <nnn> is an integer (1-3 digits); the character with code <nnn> is output (NB : <nnn> is read as decimal)

Note that \l, \nnn and \\ are interpreted differently when character escapes are in effect. See section 2.15.2.1.

Escape sequences to include arguments from Arguments. Each time a % escape sequence is found in Format the next argument from Arguments is formatted according to the specification.

%t print/1 the next item (mnemonic: term)
%w write/1 the next item
%q writeq/1 the next item
%d Write the term, ignoring operators. See also write_term/2. Mnemonic: old Edinburgh display/1
%p print/1 the next item (identical to %t)
%n Put the next item as a character (i.e., it is a character code)
%r Write the next item N times where N is the second item (an integer)
%s Write the next item as a String (so it must be a list of characters)
%f Perform a ttyflush/0 (no items used)
%Nc Write the next item Centered in N columns
%Nl Write the next item Left justified in N columns
%Nr Write the next item Right justified in N columns. N is a decimal number with at least one digit. The item must be an atom, integer, float or string.
[deprecated]swritef(-String, +Format, +Arguments)
Equivalent to writef/2, but ``writes'' the result on String instead of the current output stream. Example:
?- swritef(S, '%15L%w', ['Hello', 'World']).

S = "Hello          World"
[deprecated]swritef(-String, +Format)
Equivalent to swritef(String, Format, []).

4.31.2 Format

The format family of predicates is the most versatile and portable109Unfortunately not covered by any standard. way to produce textual output.

format(+Format)
Defined as `format(Format) :- format(Format, []).'. See format/2 for details.
format(+Format, :Arguments)
Format is an atom, list of character codes, or a Prolog string. Arguments provides the arguments required by the format specification. If only one argument is required and this single argument is not a list, the argument need not be put in a list. Otherwise the arguments are put in a list.

Special sequences start with the tilde (~), followed by an optional numeric argument, optionally followed by a colon modifier (:), 110The colon modifiers is a SWI-Prolog extension, proposed by Richard O'Keefe. followed by a character describing the action to be undertaken. A numeric argument is either a sequence of digits, representing a positive decimal number, a sequence `<character>, representing the character code value of the character (only useful for ~t) or a asterisk (*), in which case the numeric argument is taken from the next argument of the argument list, which should be a positive integer. E.g., the following three examples all pass 46 (.) to ~t:

?- format('~w ~46t ~w~72|~n', ['Title', 'Page']).
?- format('~w ~`.t ~w~72|~n', ['Title', 'Page']).
?- format('~w ~*t ~w~72|~n', ['Title', 46, 'Page']).

Numeric conversion (d, D, e, E, f, g and G) accept an arithmetic expression as argument. This is introduced to handle rational numbers transparently (see section 4.26.2.2). The floating point conversions allow for unlimited precision for printing rational numbers in decimal form. E.g., the following will write as many 3's as you want by changing the `70'.

?- format('~50f', [10 rdiv 3]).
3.33333333333333333333333333333333333333333333333333

Example:

simple_statistics :-
    <obtain statistics>         % left to the user
    format('~tStatistics~t~72|~n~n'),
    format('Runtime: ~`.t ~2f~34|  Inferences: ~`.t ~D~72|~n',
                                            [RunT, Inf]),
    ....

will output

                             Statistics

Runtime: .................. 3.45  Inferences: .......... 60,345
format(+Output, +Format, :Arguments)
As format/2, but write the output on the given Output. The de-facto standard only allows Output to be a stream. The SWI-Prolog implementation allows all valid arguments for with_output_to/2.112Earlier versions defined sformat/3 . These predicates have been moved to the library library(backcomp). For example:
?- format(atom(A), '~D', [1000000]).
A = '1,000,000'

4.31.3 Programming Format

format_predicate(+Char, +Head)
If a sequence ~c (tilde, followed by some character) is found, the format/3 and friends first check whether the user has defined a predicate to handle the format. If not, the built-in formatting rules described above are used. Char is either a character code or a one-character atom, specifying the letter to be (re)defined. Head is a term, whose name and arity are used to determine the predicate to call for the redefined formatting character. The first argument to the predicate is the numeric argument of the format command, or the atom default if no argument is specified. The remaining arguments are filled from the argument list. The example below defines ~T to print a timestamp in ISO8601 format (see format_time/3). The subsequent block illustrates a possible call.
:- format_predicate('T', format_time(_Arg,_Time)).

format_time(_Arg, Stamp) :-
        must_be(number, Stamp),
        format_time(current_output, '%FT%T%z', Stamp).
?- get_time(Now),
   format('Now, it is ~T~n', [Now]).
Now, it is 2012-06-04T19:02:01+0200
Now = 1338829321.6620328.
current_format_predicate(?Code, ?:Head)
True when ~Code is handled by the user-defined predicate specified by Head.