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.
writef(Atom, []). See writef/2 
for details.
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.16.1.3.
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. | 
?- swritef(S, '%15L%w', ['Hello', 'World']). S = "Hello World"
swritef(String, Format, []).
The format family of predicates is the most versatile and portable129Unfortunately not covered by any standard. way to produce textual output.
format(Format) :- format(Format, []).'. See
format/2 
for details.Special sequences start with the tilde (~`<character>, 
representing the character code value of the character (only useful for
~t) or a asterisk (*.~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.27.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 `50'.
?- format('~50f', [10 rdiv 3]).
3.33333333333333333333333333333333333333333333333333
~
a
c
dThe colon modifier (e.g., ~:d) causes the number to be 
printed according to the locale of the output stream. See section 
4.23.
D~:d, 
but using the fixed English locale.
e%.<precision>e.
E
f
g
G
i
I_). The argument describes the size of each digit group. 
The default is 3. See also section 
2.16.1.5. For example:
?- A is 1<<100, format('~10I', [A]).
1_2676506002_2822940149_6703205376
knNpq
r~16r prints its argument hexadecimal. The argument should 
be in the range [2, ... , 36]. Lowercase letters are used for 
digits above 9. The colon modifier may be used to form locale-specific 
digit groups.
Rs[]@current_output stream is inserted at this place. Goal 
is called in the module calling format/3. 
This option is not present in the original definition by Quintus, but 
supported by some other Prolog systems.
t~t statements between the tab stops. This space is padded 
with spaces by default. If an argument is supplied, it is taken to be 
the character code of the character used for padding. This can be used 
to do left or right alignment, centering, distributing, etc. See also ~| 
and ~+ to set tab stops. A tab stop is assumed at the start 
of each line.
|~t's to be distributed between the previous and this tab 
stop.
+~|) relative to the last tab stop or the 
beginning of the line if no tab stops are set before the ~+. 
This constructs can be used to fill fields. The partial format sequence 
below prints an integer right-aligned and padded with zeros in 6 
columns. The ... sequences in the example illustrate that the integer is 
aligned in 6 columns regardless of the remainder of the format 
specification.
        format('...~|~`0t~d~6+...', [..., Integer, ...])
wWformat('~W', [Term, [numbervars(true)]]). This option is 
SWI-Prolog specific.
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
library(backcomp). For example:
?- format(atom(A), '~D', [1000000]). A = '1,000,000'
~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.
~