# 字符串转换与格式化

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

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 的字符串。

  格式码 必须是以下其中之一, `'e'`, `'E'`, `'f'`, `'F'`, `'g'`, `'G'` 或者 `'r'`。对于 `'r'` , 提供的 精度 必须是0。`'r'` 格式码指定了标准函数 `repr()` 格式。

  flags 可以为零或者其他值 `Py_DTSF_SIGN`, `Py_DTSF_ADD_DOT_0` 或 `Py_DTSF_ALT` 或其组合：

  - `Py_DTSF_SIGN` 表示总是在返回的字符串前附加一个符号字符，即使 val 为非负数。

  - `Py_DTSF_ADD_DOT_0` 表示确保返回的字符串看起来不像是一个整数。

  - `Py_DTSF_ALT` 表示应用 "替代的" 格式化规则。 相关细节请参阅 `PyOS_snprintf()` `'#'` 定义文档。

  如果 ptype 不为 `NULL`，则它指向的值将被设为 `Py_DTST_FINITE`, `Py_DTST_INFINITE` 或 `Py_DTST_NAN` 中的一个，分别表示 val 是一个有限数字、无限数字或非数字。

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

  Added in version 3.1.

int PyOS_stricmp(const char *s1, const char *s2)

  不区分大小写的字符串比较。 除了忽略大小写之外，该函数的工作方式与 `strcmp()` 相同。

int PyOS_strnicmp(const char *s1, const char *s2, Py_ssize_t size)

  不区分大小写的字符串比较。 除了忽略大小写之外，该函数的工作方式与 `strncmp()` 相同。