# 字符串转换与格式化

用于数字转换和格式化字符串输出的函数

int PyOS_snprintf(char *str, size_t size, const char *format, ...)
  属于 稳定 ABI.

  根据格式字符串 format 和额外参数，输出不超过 size 个字节到 str。参见 Unix 手册页面 snprintf(3) 了解更多。

int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
  属于 稳定 ABI.

  根据格式字符串 format 和变量参数列表 va，输出不超过 size 个字节到 str。参见 Unix 手册页面 vsnprintf(3) 了解更多。

`PyOS_snprintf()` 和 `PyOS_vsnprintf()` 包装 C 标准库函数 `snprintf()` 和 `vsnprintf()`。它们的目的是保证在极端情况下的一致行为，而标准 C 的函数则不然。

此包装器会确保 `str[size-1]` 在返回时始终为 `'\0'`。它们从不写入超过 size 字节 (包括末尾的 `'\0'`) 到 str。两个函数都要求 `str != NULL`, `size > 0`, `format != NULL` 且 `size < INT_MAX`。请注意这意味着不存在可确定所需缓冲区大小的 C99 `n = snprintf(NULL, 0, ...)` 的等价物。

这些函数的返回值（ rv ）应按照以下规则被解释：

- 当 `0 <= rv < size` 时，输出转换即成功并将 rv 个字符写入到 str (不包括末尾 `str[rv]` 位置的 `'\0'` 字节)。

- 当 `rv >= size` 时，输出转换会被截断并且需要一个具有 `rv + 1` 字节的缓冲区才能成功执行。在此情况下 `str[size-1]` 为 `'\0'`。

- 当 `rv < 0` 时，在此场景下输出转换将失败并且 `str[size-1]` 为 `'\0'`，但 str 的其余部分是未定义的。错误的确切原因取决于底层平台。

以下函数提供与语言环境无关的字符串到数字转换。

unsigned long PyOS_strtoul(const char *str, char **ptr, int base)
  属于 稳定 ABI.

  根据给定的 `base` 将 `str` 中字符串的初始部分转换为 unsigned long 值，基数必须在 `2` 至 `36` 之间（包括边界值），或者为特殊值 `0`。

  空白前缀和字符大小写将被忽略。如果 `base` 为零则会查找 `0b`、`0o` 或 `0x` 前缀以确定基数。如果没有则默认基数为 `10`。基数必须为 0 或在 2 和 36 之间（包括边界值）。如果 `ptr` 不为 `NULL` 则它将包含一个指向扫描结束位置的指针。

  如果转换后的值不在对应返回类型的取值范围之内，则会发生取值范围错误 (`errno` 被设为 `ERANGE`) 并返回 `ULONG_MAX`。如果无法执行转换，则返回 `0`。

  另请参阅 Unix 手册页 strtoul(3)。

  Added in version 3.2.

long PyOS_strtol(const char *str, char **ptr, int base)
  属于 稳定 ABI.

  根据给定的 `base` 将 `str` 中字符串的初始部分转换为 long 值，基数必须在 `2` 至 `36` 之间（包括边界值），或者为特殊值 `0`。

  类似于 `PyOS_strtoul()`，但改为返回 long 值，溢出时返回 `LONG_MAX`。

  另请参阅 Unix 手册页 strtol(3)。

  Added in version 3.2.

double PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception)
  属于 稳定 ABI.

  将字符串 `s` 转换为 double 类型，失败时会引发 Python 异常。接受的字符串集合对应于可被 Python 的 `float()` 构造器所接受的字符串集合，除了 `s` 必须没有前导或尾随空格。转换独立于当前的语言区域。

  如果 `endptr` 是 `NULL`，则转换整个字符串。如果字符串不是浮点数的有效表示，则引发 `ValueError` 并返回 `-1.0`。

  如果 `endptr` 不是 `NULL`，尽可能多的转换字符串并将 `*endptr` 设置为指向第一个未转换的字符。如果字符串的初始段不是浮点数的有效的表达方式，将 `*endptr` 设置为指向字符串的开头，引发 ValueError 异常，并且返回 `-1.0`。

  如果 `s` 表示一个大到无法存储为 float 的值（例如，`"1e500"` 在许多平台上就是这样一个字符串）则当 `overflow_exception` 为 `NULL` 时将返回 `Py_INFINITY` (具有适当的正负号) 并且不会设置任何异常。否则，`overflow_exception` 必须指向一个 Python 异常对象；将引发该异常并返回 `-1.0`。在这两种情况下，都会将 `*endptr` 设为指向被转换值之后的第一个字符。

  如果在转换期间发生任何其他错误（比如一个内存不足的错误），设置适当的 Python 异常并且返回 `-1.0`。

  Added in version 3.1.

char *PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype)
  属于 稳定 ABI.

  将 double val 转换为一个使用给定的 format_code, precision 和 flags 的字符串。

  format_code 必须是以下其中之一：`'e'`, `'E'`, `'f'`, `'F'`, `'g'`, `'G'` 或 `'r'`。对于 `'r'`，提供的 precision 必须为 0 且会被忽略。`'r'` 格式码指定了标准 `repr()` 格式。

  flags 可以为零或多个下列值进行或运算的结果：

  Py_DTSF_SIGN

    总是在返回的字符串前加一个正负号字符，即使 val 为非负数。

  Py_DTSF_ADD_DOT_0

    确保返回的字符串看起来不像是一个整数。

  Py_DTSF_ALT

    应用“替代”格式化规则。请参阅 `PyOS_snprintf()` `'#'` 格式符的文档了解详情。

  Py_DTSF_NO_NEG_0

    负零将被转换为正零。

    Added in version 3.11.

  如果 ptype 不为 `NULL`，则它指向的值将根据 val 的类型被设为以下常量之一：

  *ptype | val 的类型
  --- | ---
  Py_DTST_FINITE | 有限数字
  Py_DTST_INFINITE | 无穷大数字
  Py_DTST_NAN | 非数字

  返回值是一个指向包含转换后字符串的 buffer 的指针，如果转换失败则为 `NULL`。调用方要负责调用 `PyMem_Free()` 来释放返回的字符串。

  Added in version 3.1.

int PyOS_mystricmp(const char *str1, const char *str2)
int PyOS_mystrnicmp(const char *str1, const char *str2, Py_ssize_t size)
  属于 稳定 ABI.

  不区分大小写的字符串比较。这些函数的工作方式（分别）与 `strcmp()` 和 `strncmp()` 几乎一样，只是它们会忽略 ASCII 字符的大小写。

  如果字符串相等则返回 `0`，如果 str1 的词典排序在 str2 之前则返回负值，或者如果排序在其后则返回正值。

  在 str1 或 str2 参数中，NUL 字符表示字符串结束。对于 `PyOS_mystrnicmp()`，size 参数给出了字符串的最大长度，就像 NUL 出现在由 size 给出的索引位置。

  这些函数不使用语言区域设置。

int PyOS_stricmp(const char *str1, const char *str2)
int PyOS_strnicmp(const char *str1, const char *str2, Py_ssize_t size)

  忽略大小写的字符串比较。

  在 Windows 上，它们分别是 `stricmp()` 和 `strnicmp()` 的别名。

  在其他平台上，它们分别是 `PyOS_mystricmp()` 和 `PyOS_mystrnicmp()` 的别名。

# 字符分类与转换

下列宏提供了独立于语言区域 (不同于 C 标准库 `ctype.h`) 的字符分类与转换。其参数必须是一个有符号或无符号的 char 值。

Py_ISALNUM(c)

  如果字符 c 为字母数字类字符则返回真值。

Py_ISALPHA(c)

  如果字符 c 为字母类字符 (`a-z` 和 `A-Z`) 则返回真值。

Py_ISDIGIT(c)

  如果字符 c 为十进制数码 (`0-9`) 则返回真值。

Py_ISLOWER(c)

  如果字符 c 为小写 ASCII 字母 (`a-z`) 则返回真值。

Py_ISUPPER(c)

  如果字符 c 是一个大写 ASCII 字母 (`A-Z`) 则返回真值。

Py_ISSPACE(c)

  如果字符 c 是一个空白字符 (空格符，制表符，回车符，换行符，垂直制表符或换页符) 则返回真值。

Py_ISXDIGIT(c)

  如果字符 c 是一个十六进制数码 (`0-9`, `a-f` 和 `A-F`) 则返回真值。

Py_TOLOWER(c)

  返回字符 c 的小写形式。

Py_TOUPPER(c)

  返回字符 c 的大写形式。