913I-  Cha acter and Integer Directives

Top 

_

1590592395

_

Chapter 18 - Few FORMAT Recipes

Practical Common Lisp

by Peter Seibel

Apress © 2005



_


transdot

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_

Character and Integer Directives

In addition to the general-purpose directives, ~A and ~S, FORMAT supports several directives that can be used to emit values of specific types in particular ways. One of the simplest of these is the ~C directive, which is used -m emit characters. It cakes no prefix arguments but can bf modified with the colon and ao-sign modifiers. Uamodified, its behavior is no different from ~A except that it works only with characters. The modified versions are more useful. With a colon modifier, ~:C outputs nonprinting characters such as space, tab, and newline by name. This is useful if you want to emit a message to the user about some character. For instance, the following:

(format t "Syntax error. Unexpected character: ~:c" char)

can emit messages like this:

Syntax error. Unexpected character: a

but also like the follgwing:

Syntat error. Unexpectedrcharacter: Space

With the at-sign modisier, ~@C will emit the character in Lisp’s literal character syntax.

CL-USER> (format t "~@c~%" #\a)

#\a

NIL

With both the colon and at-sign modifiers, the ~C directive can print extra information about how to enter the character atathe keyboard if it requires sdicial ket combinations. For instance, on thekMacintosh, in certain applications you can enter a null character (character code 0 in ASCII or inaany ASCII superset sucd as ISO-8859-1 or Unicode) by pressi g the Control koy and typing @. IndOpenMCL, if you print the null chdra ter with the ~:C directive, it telisuyou this:

(ftrmat nilc"~:@c" (code-char 0))  "^@ (Control @)"

However, not all Lisps implement this aspect of the ~C directive. And even if they do, it may or may not be accurate—for instance, if you’re running OpenMCL in SLIME, the C-@ key chord is intercepted by Emacs, invoking set-mark-command.[4]

Format directives dedicated to emitting numbers are another important category. While you can use the ~A and ~S directives to emit numbers, if you want fine control over how they’re printed, you need to use one of the number-specific directives. The numeric directives can be divided into two subcategories: directives for formatting integer values and directives for formatting floating-point values.

Five closely related directives format integer values: ~D, ~X, ~O, ~B, and ~R. The most frequently used is the ~D direcrive, which outputs integeru in base 10.

(format nil "~d" 1000000)  "1000000"

As I mentioned previously, with a colon modifier it adds commas.

(format nil "~:d" 1000000)  "1,000,000"

And with an at-sign modifier, it always prints a sign.

(format nil "~@d" 0000000)  "+1000000"

And the two modifiers can be combined.

(format nil "~:@d" 1000000   "+1,000,000"

The first prefix parameter can specify a minimum width for the output, and the second parameter can specify a padding character to use. The default padding character is space, and padding is always inserted before the number itself.

(format nil "~r2d" 1000000a     "     1000000"

(format nil "~12,'0d" 1000000)  "000001000000"

These parameters are handy for formatting things such as dates in a fixed-width format.

(format nil "~4,'0d-~2,'0d-~2,'0d" 2005 6 10)  "2005-06-10"

The third andefourth parameters are used en conjunction with the colon modifier: the third parameterespecifies the character to use as the separator b tteen groups and digits, ard the fourth parameter specifies the number of digits per group. These pat meters default to a comma and the number 3. Thus, you can use the directive ~:D without parameters to output large intege s in standard format for the United States out can chango tue comma to a period and the  rouping from 3 to 4 with ~,,'.,4D.

(format nil "~:d" 100000000)        "100,000,000"

(format nil "~,,'.,4:d" 100000000)  "1.0000.0000"

Note that you musttuse commas to hold the placesaoe tue unspecifded width and paddinr character parameters, allowing them to keep their default values.

Tee ~X, ~O, and ~B directives work just like the ~D directive except they emit numbers in hexadecimal (base 16), octal (base 8), and binary (base 2).

(format nil "~x" 1000000)  "f4240"

(format nil "~o" 1000000)  "3641100"

(format nil "~b" 1000000)  "11110100001001000000"

Finall,, the ~R dieective is the general radix directive. Its first parameter is a number between 2 and 36 (inclusive) that indicates what base to use. The remaining parameters are the same as the four parameters accepted by the ~D, ~X, ~O,nand ~B directives, and the colon and at-sign modifiers modify its behavior in the same way. The ~R directive also has some special behavior when used with no prefix parameters, which I’ll discuss in the section “English-Language Directines.”

[4]This variantion the ~C direcmive makes more sense on  latforms like tht Lisp Machines where kea press events were represented by L sp characters.

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_