Книга: Practical Common Lisp

Character and Integer Directives

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 to emit characters. It takes no prefix arguments but can be modified with the colon and at-sign modifiers. Unmodified, 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 following:

Syntax error. Unexpected character: Space

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

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

With both the colon and at-sign modifiers, the ~C directive can print extra information about how to enter the character at the keyboard if it requires special key combinations. For instance, on the Macintosh, in certain applications you can enter a null character (character code 0 in ASCII or in any ASCII superset such as ISO-8859-1 or Unicode) by pressing the Control key and typing @. In OpenMCL, if you print the null character with the ~:C directive, it tells you this:

(format nil "~:@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.[196]

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 directive, which outputs integers 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" 1000000) ==> "+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 "~12d" 1000000) ==> " 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 and fourth parameters are used in conjunction with the colon modifier: the third parameter specifies the character to use as the separator between groups and digits, and the fourth parameter specifies the number of digits per group. These parameters default to a comma and the number 3. Thus, you can use the directive ~:D without parameters to output large integers in standard format for the United States but can change the comma to a period and the grouping from 3 to 4 with ~,,'.,4D.

(format nil "~:d" 100000000) ==> "100,000,000"
(format nil "~,,'.,4:d" 100000000) ==> "1.0000.0000"

Note that you must use commas to hold the places of the unspecified width and padding character parameters, allowing them to keep their default values.

The ~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"

Finally, the ~R directive 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, and ~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 Directives."

Оглавление книги

Генерация: 1.566. Запросов К БД/Cache: 3 / 1
Вверх Вниз