# 4.7 字符串格式化

格式化指，通过对常量字符串进行替换，从而计算并构造出新字符串的操作。这些常量字符控制如何进行计算，以及如何显示这些字符串；这种操作称为格式化字符串。

格式化字符串通常在调试，记录时非常有用。实际上，函数 message 和 error 同样提供本节介绍的字符串格式化操作；它们和 format-message 的不同点仅仅在于它们如何使用结果。

函数: format string \&rest objects

该函数使用 objects 替换 string 种特定的字符，生成并返回另一个字符串。参数 objects 即是参与计算的值。

string 中除去特定字符外的所有字符都会原样输出，包括它们的文本属性。objects 中的文本属性也会被拷贝并按照原样输出。

生成的字符串很可能不是完全新创建的。举个例子，若 x 是字符串 "foo"，那么表达式 (eq x (format x)) 和 表达式 (eq x (format "%s" x)) 很可能都为 t。

函数: format-message string \&rest objects

该函数和 format 非常相似，不同点在于该函数同样提供重音和撇号的转换。

通常重音和撇号会对应到斜引号，举个例子，"Missing \`%s‘" 会生成 "Missing ’foo‘"。详情查阅 文本引用风格，以了解如何影响这类转换。

通常，格式化标记是一个以 '%' 开头的字符序列。当遇到 '%d' 时，函数 format 会将其替换为 参数 objects 中某个参数对应的打印表示。举个例子：

```
(format "The value of fill-column is %d." fill-column)
     ⇒ "The value of fill-column is 72."
```

format 将字符 '%' 解释为格式化标记，因此该函数的第一个参数需要和后续的参数匹配。这里有一个例子：

```
(format "%s" arbitrary-string)
```

每个特定的格式化标记都要对应着特定类型的数据。如果你提供的值和格式化标记不对应，则会抛出错误。

这里有一个格式化标记集合：

'%s'

使用对象的打印表示替换该标记（使用princ 而非 prin1 输出函数）。中间不会出现 '"'字符，且符号出现的地方也不会有 '\\' 字符。

若对象是字符串，那么还会将文本属性也复制到输出中。'%s'本身的文本属性也会被拷贝，但优先拷贝对象的属性

'%S'

使用对象的打印表示替换该标记（使用 print1 输出函数）。中间会出现引号。因此，字符串会被 '"' 包围起来，且'\\' 会出现在必要的地方。

'%o'

使用对象的八进制表示来替换标记。若传入值为负数，那么输出结果会很依赖具体平台。传入值同样可以为浮点数，在传入后，会将其小数部分略去。

'%d'

使用对象的十进制表示来替换标记。传入值同样可以为浮点数，传入后，会将其小数部分略去。

'%x'

'%X'

使用对象的十六进制来替换标记。传入值为负数时，输出结果会很依赖具体平台。其中 '%x' 使用小写字母，'%X' 使用大写字母。传入值同样可以为浮点数，传入后会将小数部分略去。

'%c'

使用字符替换标记。

'%e'

使用浮点数指数记法来替换标记。

'%f'

使用浮点数小数表示来替换标记。

'%g'

使用指数记法或小数表示来替换标记。（TODO）

'%%'&#x20;

使用 '%' 替代标记。该标记不使用值。例如，(format "%% %d" 30) 返回 "% 30"。

其他任何格式化标记都会抛出 'Invalid format operation' 错误。

这里有几个例子，其中假定使用默认的 text-quoting-style 设置：

```
(format "The octal value of %d is %o,
         and the hex value is %x." 18 18 18)
     ⇒ "The octal value of 18 is 22,
         and the hex value is 12."

(format-message
 "The name of this buffer is ‘%s’." (buffer-name))
     ⇒ "The name of this buffer is ‘strings.texi’."

(format-message
 "The buffer object prints as `%s'." (current-buffer))
     ⇒ "The buffer object prints as ‘strings.texi’."
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://emacs-lisp.ivory.cafe/zi-fu-chuan-he-zi-fu/zi-fu-chuan-ge-shi-hua.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
