zoukankan      html  css  js  c++  java
  • printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf

    总览 (SYNOPSIS)

    #include <stdio.h>

    int printf(const char *format, ...);
    int fprintf(FILE *stream, const char *format, ...);
    int sprintf(char *str, const char *format, ...);
    int snprintf(char *str, size_t size, const char *format, ...);

    #include <stdarg.h>

    int vprintf(const char *format, va_list ap);
    int vfprintf(FILE *stream, const char *format, va_list ap);
    int vsprintf(char *str, const char *format, va_list ap);
    int vsnprintf(char *str, size_t size, const char *format, va_list ap);

    描述 (DESCRIPTION)

    printf 系列 函数 根据 下述的 format 参数 生成 输出内容. printfvprintf 函数 把 输出内容 写到 stdout, 即 标准输出流; fprintfvfprintf 函数 把 输出内容 写到 给定的 stream 流; sprintf, snprintf, vsprintfvsnprintf 函数 把 输出内容 存放到 字符串 str 中.

    这些 函数 由 格式字符串 format 参数 控制 输出内容, 它 指出 怎么样 把 后面的 参数 (或 通过 stdarg(3) 的 变长参数机制 访问的 参数) 转换成 输出内容.

    这些 函数 返回 打印的 字符 数量 (不包括 字符串 结尾用的 `'). snprintfvsnprintf 的 输出 不会 超过 size 字节 (包括了 结尾的 `'), 如果 因为 这个 限制 导致 输出内容 被截断, 则 函数 返回 -1.

    格式字符串 (format 参数) 由 零到多个 指令 组成: 普通字符 (除 % 外), 它们 被 原封不动的 送到 输出流; 以及 格式转换说明 (conversion specification), 每个 格式转换说明 都会 从后面 提取 零到多个 参数. 格式转换说明 由 % 字符 引导开始. 参数 必须 正确的 对应到 格式转换符 (conversion specifier) 上. 下述 字符 按顺序 列在 % 后面:

    *
    零个 或 多个 下列 标志:
    #
    指出 数值 应该 转换成 "其他形式". 对于 c, d, i, n, p, s, 和 u 格式转换, 这个选项 没有 影响. 对于 o 格式转换, 数值的 精度 被提高, 使 输出字符串的 第一个 字符 为零 (除非 打印 一个零值 时, 明确 定义 精度 为零). 对于 xX 格式转换, 非零数值 前面 会添加 `0x' 字符串 (或 X 格式转换 的 `0X' 字符串). 对于 e, E, f, g, 和 G 格式转换, 其结果 始终 含有一个 十进制小数点, 即使 后面 没有 数字 (一般说来, 只有当 格式转换 后, 小数点 后面 有数字时 才显示 小数点). 对于 gG 格式转换, 将不删去 结果末尾的 零, 其他情况下 这些 零 应该 删掉.
    0
    指出 用零 填充 结果. 所有的 格式转换, 除了 n, 转换结果 的 左边 用零 填充, 而不是 空格. 如果 数值转换 时 给定了 精度, (d, i, o, u, i, x, 和 X), 则 忽略 0 标志.
    -
    (负位宽标志) 指出 转换结果 必须 在 位边界 上 向左边 对齐. 除了 n 格式转换, 转换结果 的 右边 用空格 填充, 而不是 在左边 填充 空格或零. 如果 同时 给出了 -0 ,- 覆盖 0 .
    ' '
    (空格) 指出 在 通过 有符号数(signed) 格式转换 ( d, e, E, f, g, G, 或 i ) 产生的 正数 前面 留一个 空格.
    +
    指出 有符号数 格式转换 产生的 结果 前面 始终 有一个 正负符号. 如果 同时 给出了 + 和 空格, 则 + 覆盖 空格.
    '
    指出 在 数字 参数 中, 如果 locale 给出 相关信息, 输出结果 将被 分组. 注意, 许多 版本 的 gcc 不能 理解 这个选项, 因而会 产生 一个警告.
    *
    一个 可选的 十进制数, 指出 最小的 位宽. 如果 格式转换后 产生的 字符数少于 位宽, 则 左边 用 空格 填充 (或者 填充 右边, 如果 给出了 向左对齐标志), 直到 填满 指定的 位宽.
    *
    一个 可选的 精度, 格式是 一个 句号(`.') 后面 跟着 一个 可选的 数字. 如果 没有 给出 这个 数字, 则 精度 取为 零. 这样就 指定了 d, i, o, u, x, 和 X 格式转换 显示的 最小位数, e, E, 和 f 格式转换 小数点 后面 显示的 位数, gG 格式转换 显示的 最大有效位数(significant digits), 或 s 格式转换 打印 某个 字符串的 最多 字符数目.
    *
    可选的 字符 h, 指出 后面的 d, i, o, u, x, 或 X 格式转换 对应为 short intunsigned short int 的 参数, 或者是 后面的 n 格式转换 对应为 指向 short int 参数 的 指针.
    *
    可选的 字符 l (ell) 指出 后面的 d, i, o, u, x, 或 X 格式转换 应用到 指向 long intunsigned long int 参数 的 指针, 或者 后面的 n 格式转换 对应为 指向 long int 参数 的 指针. Linux 提供 和 ANSI 不兼容 的 双 l 标志, 作为 q L 的 同义词. 因此 ll 可以 结合 浮点格式转换 使用. 但是 强烈 反对 这个 用法.
    *
    字符 L 指出 后面的 e, E, f, g, 或 G 格式转换 对应 long double 参数, 或者 让 后面的 d, i, o, u, x, 或 X 格式转换 对应 long long 参数. 注意 long long 没有在 ANSI C 中 声明, 因此 不能够 移植到 所有的 体系平台 上.
    *
    可选的 字符 q 等于 L. 参考 STANDARDS 和 BUGS 节 关于 ll, L, 和 q 的 叙述.
    *
    字符 Z 指出 后面的 整数 (d, i, o, u, x, 或 X) 格式转换 对应 size_t 参数.
    *
    指出 采用 格式转换类型 的 字符.

    可以 用 星号 `*' 代替 数字 指定 域宽 或 精度, 也可以 两者 同时 指定. 这种情况下 要求 用一个 int 参数 指出 域宽 或 精度. 负域宽 被认为是 正域宽 跟在 向左对齐标志 后面; 负精度 被认为是 精度 丢失.

    格式转换符(specifier) 及其 含义 如下:

    diouxX
    int 形 (或 合适的 变量) 参数 转换输出为 有符号十进制数 (di), 无符号八进制数 (o), 无符号十进制数 (u), 或者 无符号十六进制数 (xX). x 格式转换 用 小写字母 abcdef ; X 格式转换 用 大写字母 ABCDEF . 精度值 (如果给出) 指出 必须显示的 最少 数字; 如果 转换结果 少于 这个 要求, 则用 零 填补 转换结果 的 左边.
    eE
    double 参数 舍入后 转换为 [-]d.ddde*(Pmdd 的 格式, 这个格式 的 小数点 前面 有 一位 数字, 后面 表示 精度; 如果没有 指出 精度, 则意味着 精度是 6; 如果 精度 是 0, 则不显示 小数点. E 格式转换 使用 字母 E (而不是 e) 要求 引入 指数. 指数 至少 包含 两个 数字; 如果 值 是 零, 则 指数 是 00.
    f
    double 参数 舍入后 转换为 [-]ddd.ddd 的 十进制 表达式, 这个格式 小数点 后面 的 数字 表示 精度. 如果 没有 指出 精度, 则意味着 精度是 6; 如果 显式 给出 精度 是 0, 则不显示 小数点. 如果 显示了 小数点, 则 小数点 前面 至少有 一位 数字.
    g
    double 参数 以 fe (或者 G 格式转换的 E 标志) 的 形式 转换. 其精度 指出 有符号数字 的 数目. 如果 没有 指出精度, 则默认为 6; 如果 精度 是 零, 则按 1 处理. 如果 格式转换后 其 指数 小于 -4 或者 大于等于 其精度, 则 使用 e 形式. 转换结果 消除了 分数部分 末尾的 零; 小数点 前面 至少有 一位 十进制数字.
    c
    int 参数 转换为 unsigned char, 然后 输出 对应的 字符.
    s
    认为 ``char *'' 参数 是 指向 字符形数组 的 指针 (指向 字符串). Printf 输出 数组内的 字符, 直到 遇上 (但不包括) 结束字符 NUL ; 如果 给出了 精度值, printf 不会 输出 多于 这个值 的 字符, 也不需要 提供 NUL 结束符; 如果 没有 给出 精度值, 或 精度值 大于 数组长度, 则 数组内一定要 包括 一个 NUL 字符.
    p
    将以 十六进制数 打印 ``void *'' 指针参数 (就象是 %#x%#lx).
    n
    将 目前 已经 输出的 字符数目 存储在 ``int *'' (或变量) 指针参数 指向的 地址. 不转换 任何参数.
    %
    输出 一个 '%'. 不转换 任何参数. 完整的 写法 是 `%%'.

    不指定 域宽 或 偏小的 域宽 不会 导致 内容 被截断; 如果 转换结果 的 长度超过 其域宽, 则 域宽 会 扩大到 容下 完整的 结果.

    示例 (EXAMPLES)


    以 `Sunday, July 3, 10:02' 格式 显示 日期, 其中 weekdaymonth 是 字符串指针:

    #include <stdio.h>
    fprintf(stdout, "%s, %s %d, %.2d:%.2d
    ",
            weekday, month, day, hour, min);
    

    显示 五位 十进制数:

    #include <math.h>
    #include <stdio.h>
    fprintf(stdout, "pi = %.5f
    ", 4 * atan(1.0));
    

    分配 128 个 字节 的 字符串 空间 保存 打印 结果:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    char *newfmt(const char *fmt, ...)
    {
                    char *p;
                    va_list ap;
                    if ((p = malloc(128)) == NULL)
                            return (NULL);
                    va_start(ap, fmt);
                    (void) vsnprintf(p, 128, fmt, ap);
                    va_end(ap);
                    return (p);
    }
    

    另见 (SEE ALSO)

    printf(1), scanf(3)

    标准 (STANDARDS)

    fprintf, printf, sprintf, vprintf, vfprintf, 和 vsprintf 函数 遵循 ANSI C3.159-1989 (``ANSI C'') 标准.

    qBSD 4.4long long 形 的 标志, 而 整数格式转换 的 llL 是 GNU 的 标志.

    这些 函数 的 Linux 版本 基于 GNU libio 库. 有关细节 可以 查看 GNU libc (glibc-1.08)info 文档.

    BUGS

    在 Linux 下 某些 浮点格式转换 会导致 内存泄露.

    这些函数 都遵循 完整的 ANSI C3.159-1989, 但是 提供了 附加的 q, Z' 标志, 并给了 Ll 标志 更多的 特性. 后者 可能会 被认为 是 bug, 因为 它 改变了 ANSI C3.159-1989 中 定义的 特性.

    用 零 填充 的 %p 格式转换 (既可以用 0 标志, 也可以用 精度), 对 %n%p 格式转换 使用 # (即不处理), 以及 某些 不标准的 荒谬 组合; 这些 组合 应当 避免.

    某些 ANSI C 定义 的 标志 组合 没有 意义 (如 %Ld). 即使 在 Linux 机器上 定义的 比较好, 但是 其他 体系结构 不一定 有相同的 结果. 因此 最好 别用 While they may have a well-defined behaviour on Linux, this need not to be so on other architectures. Therefore it usually is better not to use flags that are not defined by ANSI C at all, i.e. use q instead of L in combination with diouxX conversions or ll.

    q 的 用法 和 BSD 4.4 上 不一样, 它 可能 用在 浮点格式转换 上, 即等于 L.

    因为 sprintfvsprintf 不设定 字符串的 长度, 调用者 必须小心 别让它 从 有效空间 溢出; 这一点通常 不能 保证. 

  • 相关阅读:
    poj 2312 Battle City
    poj 2002 Squares
    poj 3641 Pseudoprime numbers
    poj 3580 SuperMemo
    poj 3281 Dining
    poj 3259 Wormholes
    poj 3080 Blue Jeans
    poj 3070 Fibonacci
    poj 2887 Big String
    poj 2631 Roads in the North
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11097583.html
Copyright © 2011-2022 走看看