`
灵动的水
  • 浏览: 194516 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

fprintf ,vfprintf,sprintf..用法区别

阅读更多
今天在《Unix/Linux编程实践教程》书上,看到第八章8.5小题,不知道如何有这种输出结果,在网上搜了搜,自己总结:
  fprintf函数将格式化的信息先输出到指定的缓冲流区域中,并未直接写到文件中,可能是因为读写缓存的原因,故在执行fork后,之前的输出就有了两个备份,故而得到输出结果。
转自:http://fishsman.blog.sohu.com/160946978.html


printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - 输出格式转换

NAME
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 参数 生成 输出内容. printf 和 vprintf 函数 把 输出内容 写到 stdout, 即 标准输出流; fprintf 和 vfprintf 函数 把 输出内容 写到 给定的 stream 流; sprintf, snprintf, vsprintf 和 vsnprintf 函数 把 输出内容 存放到 字符串 str 中.

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

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

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

*
零个 或 多个 下列 标志:
#
指出 数值 应该 转换成 "其他形式". 对于 c, d, i, n, p, s, 和 u 格式转换, 这个选项 没有 影响. 对于 o 格式转换, 数值的 精度 被提高, 使 输出字符串的 第一个 字符 为零 (除非 打印 一个零值 时, 明确 定义 精度 为零). 对于 x 和 X 格式转换, 非零数值 前面 会添加 `0x' 字符串 (或 X 格式转换 的 `0X' 字符串). 对于 e, E, f, g, 和 G 格式转换, 其结果 始终 含有一个 十进制小数点, 即使 后面 没有 数字 (一般说来, 只有当 格式转换 后, 小数点 后面 有数字时 才显示 小数点). 对于 g 和 G 格式转换, 将不删去 结果末尾的 零, 其他情况下 这些 零 应该 删掉.
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 格式转换 小数点 后面 显示的 位数, g 和 G 格式转换 显示的 最大有效位数(significant digits), 或 s 格式转换 打印 某个 字符串的 最多 字符数目.
*
可选的 字符 h, 指出 后面的 d, i, o, u, x, 或 X 格式转换 对应为 short int 或 unsigned short int 的 参数, 或者是 后面的n 格式转换 对应为 指向 short int 参数 的 指针.
*
可选的 字符 l (ell) 指出 后面的 d, i, o, u, x, 或 X 格式转换 应用到 指向 long int 或 unsigned 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 形 (或 合适的 变量) 参数 转换输出为 有符号十进制数 (d 和 i), 无符号八进制数 (o), 无符号十进制数 (u), 或者 无符号十六进制数 (x 和 X). x 格式转换 用 小写字母 abcdef ; X 格式转换 用 大写字母 ABCDEF . 精度值 (如果给出) 指出 必须显示的 最少 数字; 如果 转换结果 少于 这个 要求, 则用 零 填补 转换结果 的 左边.
eE
将 double 参数 舍入后 转换为 [-]d.ddde\*(Pmdd 的 格式, 这个格式 的 小数点 前面 有 一位 数字, 后面 表示 精度; 如果没有 指出 精度, 则意味着 精度是 6; 如果 精度 是 0, 则不显示 小数点. E 格式转换 使用 字母 E (而不是 e) 要求 引入 指数. 指数 至少 包含 两个 数字; 如果 值 是 零, 则 指数 是 00.
f
将 double 参数 舍入后 转换为 [-]ddd.ddd 的 十进制 表达式, 这个格式 小数点 后面 的 数字 表示 精度. 如果 没有 指出 精度, 则意味着 精度是 6; 如果 显式 给出 精度 是 0, 则不显示 小数点. 如果 显示了 小数点, 则 小数点 前面 至少有 一位 数字.
g
将 double 参数 以 f 或 e (或者 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' 格式 显示 日期, 其中 weekday 和 month 是 字符串指针:

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

显示 五位 十进制数:

#include <math.h>#include <stdio.h>fprintf(stdout, "pi = %.5f\n", 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'') 标准.

q 是 BSD 4.4 对 long long 形 的 标志, 而 整数格式转换 的 ll 或 L 是 GNU 的 标志.

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

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

这些函数 都遵循 完整的 ANSI C3.159-1989, 但是 提供了 附加的 q, Z 和 ' 标志, 并给了 L 和 l 标志 更多的 特性. 后者 可能会 被认为 是 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. useq instead of L in combination with diouxX conversions or ll.

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

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

[中文版维护人]
徐明 <xuming@users.sourceforge.net>

[中文版最新更新]
2004/11/4

《中国Linux论坛man手册页翻译计划》
分享到:
评论

相关推荐

    PHP fprintf()函数用法讲解

    `fprintf()` 函数与 `printf()`、`sprintf()`、`vprintf()`、`vsprintf()` 和 `vfprintf()` 等函数密切相关。它们的区别在于输出目的地的不同:`printf()` 直接输出到浏览器,`fprintf()` 输出到文件,`sprintf()` ...

    printf函数族用法大全

    - **功能**: `vfprintf`函数与`fprintf`类似,接受`va_list`类型的参数`ap`,用于处理不定数量的参数。 - **返回值**: 成功时返回实际输出的字符数;失败时返回-1。 **示例**: ```c #include &lt;stdio.h&gt; #include ...

    iozone.txt

    11. printf()/fprintf()/sprintf()/snprintf()/vprintf()/vfprintf()/vsprintf()/vsanprintf() 12. readv()/writev() 13. read()/written() 14. msgrcv()/msgsnd() 15. revc()/recvfrom()/recvmsg() 16. send()...

    C标准库源代码(学习C/C++必备)

    C标准库源代码\FPRINTF.C C标准库源代码\FPUTC.C C标准库源代码\FPUTCHAR.C C标准库源代码\FPUTS.C C标准库源代码\FPUTWC.C C 标准库源代码\FPUTWCHR.C C标准库源代码\FPUTWS.C C标准库源代码\FREAD.C C标准库源代码...

    C++宽字符用法 .

    - `vfprintf()`/`vfwprintf()`:使用参数列表格式化输出宽字符串到文件。 - `vprintf()`:使用参数列表格式化输出宽字符串到标准输出。 - `vsprintf()`/`vswprintf()`:使用参数列表格式化宽字符串。 6. **数字...

    浮点转字符串

    在这个例子中,`log` 函数接收日志级别和消息,使用 `time` 和 `localtime` 获取当前时间,再通过 `strftime` 格式化时间戳,最后用 `fprintf` 打印到标准错误输出(通常用于日志记录)。 将浮点转字符串与日志打印...

    c语言中常用的函数和头文件.docx

    如文件操作(`fclose()`, `fflush()`, `fopen()`, `freopen()`, `setbuf()`, `setvbuf()`)、格式化输入输出(`fprintf()`, `fscanf()`, `printf()`, `scanf()`, `sprintf()`, `sscanf()`, `vfprintf()`, `vprintf()...

    php常用函数列表 涉及很多好用的字符串函数

    64. **vfprintf($handle, $format, $args)**: 向文件句柄写入格式化字符串。 65. **vprintf($format, $args)**: 打印格式化后的字符串。 66. **vsprintf($format, $args)**: 返回格式化后的字符串。 67. **...

    C语言参考手册之函数库

    `printf()`, `fprintf()`, `sprintf()`, `vprintf()`, `vfprintf()`, `vsprintf()`等函数用于格式化输出数据。其中,`printf()`向标准输出设备输出数据,`fprintf()`向指定文件输出数据,`sprintf()`将格式化的数据...

    c标准库1

    - `vfprintf()`、`vprintf()` 和 `vsprintf()`:与前面的函数类似,但接受一个可变参数列表。 - `fgetc()` 和 `getchar()`:从流或标准输入读取单个字符。 - `fgets()`:从流或文件读取一行。 - `putc()` 和 `...

    Format String Exploitation Tutorial-Saif EI-Sherei

    字符串格式化漏洞通常出现在使用`printf`家族函数(如`printf`, `sprintf`, `fprintf`, `snprintf`, `vprintf`, `vfprintf`, `vsprintf`, `sprintf`, `snprintf`等)的程序中,当这些函数没有正确地处理格式化字符串...

    C头文件及其下定义的函数

    - `fprintf`, `fscanf`, `printf`, `scanf`, `sprintf`, `sscanf`, `vfprintf`, `vprintf`, `vsprintf`: 格式化输入输出。 - `fgetc`, `fgets`, `fputc`, `fputs`, `getchar`, `gets`, `putc`, `putchar`, `puts`, `...

    C语言函数精简归纳[文].pdf

    `sprintf()`、`sscanf()` 分别用于向缓冲区写入格式化字符串和从缓冲区读取格式化字符串;`vfprintf()`、`vprintf()`、`vsprintf()` 是对应的变参版本。 - 字符串输入输出:`fgetc()`、`fgets()` 用于读取单个字符...

    C_宽字符处理函数函数与普通函数对照表(转).docx

    - `fprintf()`/`fwprintf()` 对应 `printf()`/`fprintf()`: 使用变参格式化输出到文件。 - `fscanf()`/`fwscanf()` 对应 `scanf()`/`fscanf()`: 从文件进行格式化输入。 - `printf()` 对应 `printf()`: 输出格式...

    深入理解php printf() 输出格式化的字符串

    本文将深入介绍printf()函数的使用方法、格式化选项以及相关函数。 首先,printf()函数的基本语法是: ```php printf(string $format, mixed $args, mixed $...args); ``` 这里的`$format`是一个字符串,其中包含...

    Format String漏洞介绍

    这些函数包括`fprintf`、`printf`、`sprintf`、`snprintf`、`vfprintf`、`vprintf`、`vsprintf`、`vsnprintf`以及如`setproctitle`、`syslog`等其他函数。当程序员没有正确提供格式字符串(format string)或允许...

    C语言字符串和宽位处理函数

    `v*`系列函数如`vfprintf()`、`vprintf()`等使用`stdarg`宏来处理可变参数列表,提供更灵活的参数传递方式。 数字转换方面,`wcstod()`、`wcstol()`和`wcstoul()`与`strtod()`、`strtol()`和`strtoul()`对应,它们...

Global site tag (gtag.js) - Google Analytics