分享

格式化输出函数:printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf

 落寒影LIB 2014-12-11

总览 (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 的 变长参数机制 访问的 参数) 转换成 输出内容.

这些 函数 返回 打印的 字符 数量 (不包括 字符串 结尾用的 `/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 (ll) 指出 后面的 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));   //atan( ) 函数返回数值表达式的反正切弧度值。

分配 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. use q instead of L in combination with diouxX conversions or ll.

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

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

建议使用snprintf和vsnprintf。


Gcc提供的格式化规定符如下: 

%d  
十进制有符号整数 

%i  
十进制有符号整数 

注:上面这两个函数在格式化输出时用途是相同的,但在输入时却是不一样的,%i可以接受任何形式的整数,而%d却不能。 

%u  
十进制无符号整数 

%f  
输出浮点数 

%s  
输出字符串 

%c  
输出单个字符 

%p  
输出指针的值 


%e %E  
指数形式的浮点数 ,其中:%e是以小写形式输出的 %E是以大写形式输出的 

%x, %X  
无符号以十六进制表示的整数,其中:%x是以小写形式输出的 %X是以大写形式输出的 

`%g', `%G'  
根据输出数据的大小需要决定用普通形式还是指数形式的输出方式
,其中: %g是以小写形式输出的 %G是以大写形式输出的 

%o  
无符号以八进制表示的整数 

`%c  
'输出单个字符 

%n  
得到输出字符的个数,但是本参数不产生任何的输出效果
。 

`%m'  
输出错误时的相应的字符串提示。 


`%%'  
输出正文字符中的“%”字符 


说明: 
可以在"%"和字母之间插进数字表示最大场宽。例如: %3d 表示输出3位整型数, 不够3位右对齐。%9.2f 表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,小数点占一位, 不够9位右对齐。%8s 表示输出8个字符的字符串, 不够8个字符右对齐。如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出。但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出;若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出。另外, 若想在输出值前加一些0, 就应在场宽项前加个0。例如: %04d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。  
例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。 


可以在"%"和字母之间加小写字母l, 表示输出的是长型数。  
例如: %ld 表示输出long整数%lf 表示输出double浮点数 

可以控制输出左对齐或右对齐, 即在"%"和字母之间加入一个"-" 号可  
说明输出为左对齐, 否则为右对齐。例如: %-7d 表示输出7位整数左对齐%-10s表示输出10个字符左对齐。 

格式化转换的具体细则 :

1  整数转换部分 

  整数转换部分主要是'%d', '%i', '%o', '%u', '%x', 和 '%X'这几个参数命令的,由于参数的不同,可以输出不同格式的结果。如上表所列: '%d', '%i'是输出一个带符号的十进制的数,'%o', '%u', and '%x'是输出一个不带符号的数,而'%X是'%x''的大写形式。其中,针对这几种不同输出选择还有如下几个参数项: 

'-’ 表示是左对齐,一般都是右对齐的。  
'+’ 是对'%d', '%i'两个参数而言的,是指以'+’符号表示正数  
'  ' 是对'%d', '%i'两个参数而言的,如果输出不是以'+’'-’开头的,那么用空格做开头。  
'#' 是对'%o'参数而言的,将在输出的结果强制加上'0’为开头。  
' ' ' 将输出的数字以LC_NUMERIC的分类法用’,’隔开。  
'0' 将空格的地方用'0'填入。 

如果没有特别指明,被格式化的参数被默认当作整数处理,或者可以用以下的类型指定参数来进行修改,如下: 
'h' 指定传入参数是 short int 或unsigned short int类型的  
'l' 指定传入参数是 long int或unsigned long int类型的  
'q' 指定传入参数是 long long int类型的  
'Z' 指定传入参数是size_t.。  


为了方便理解给出一个例子: 

对于如下的格式化匹配字串:  
"|%5d|%-5d|%+5d|%+-5d|% 5d|%05d|%5.0d|%5.2d|%d|" 

将产生类似如下的输出: 

| 0|0 | +0|+0 | 0|00000| | 00|0| 
| 1|1 | +1|+1 | 1|00001| 1| 01|1| 
| -1|-1 | -1|-1 | -1|-0001| -1| -01|-1| 
|100000|100000|+100000| 100000|100000|100000|100000|100000| 

对于如下的格式化匹配字串:  
"|%5u|%5o|%5x|%5X|%#5o|%#5x|%#5X|%#10.8x|" 

将产生类似如下的输出: 

| 0| 0| 0| 0| 0| 0x0| 0X0|0x00000000| 
| 1| 1| 1| 1| 01| 0x1| 0X1|0x00000001| 
|100000|303240|186a0|186A0|0303240|0x186a0|0X186A0|0x000186a0| 

2 浮点数的转换部分 

  浮点数转换部分主要是'%f', '%e', '%E', '%g', 和 '%G' '这几个参数命令的,由于参数的不同,可以输出不同格式的结果。如上表所列: '%f'是输出一个比较固定形式的浮点数……其中,针对这几种不同输出选择还有如下几个参数项: 

'-’ 表示是左对齐,一般都是右对齐的。  
'+’ 是指以'+’符号表示正数  
' ' 如果输出不是以'+’'-’开头的,那么用空格做开头  
'#' 是对'%g'和'%G’参数而言的,将在输出的结果强制加上'0’为开头。  
' ' ' 将输出的数字以LC_NUMERIC的分类法用’,’隔开。  
'0' 将空格的地方用“0'填入。  
如果没有特别指定,传入的被格式化的参数默认是double类型的,可以用'L’表示是一个long double类型的。 

如下例子可以看出浮点数格式化的字串: 
如下的格式字串: 

"|%12.4f|%12.4e|%12.4g|" 

  可能产生如下的输出: 

| 0.0000| 0.0000e+00| 0| 
| 1.0000| 1.0000e+00| 1| 
| -1.0000| -1.0000e+00| -1| 
| 100.0000| 1.0000e+02| 100| 
| 1000.0000| 1.0000e+03| 1000| 
| 10000.0000| 1.0000e+04| 1e+04| 
| 12345.0000| 1.2345e+04| 1.234e+04| 
| 100000.0000| 1.0000e+05| 1e+05| 
| 123456.0000| 1.2346e+05| 1.234e+05| 

3 其他格式的转换部分 

  这部分的函数比较简单一些,具体如下: 

'%c’是指输出一个单个的字符串,默认的输出的被格式化的参数是unsigned char类型的,可以用'-’表示左对齐的。没有的别的参数,比如:  
printf ("%c%c%c%c%c", 'h', 'e', 'l', 'l', 'o'); 

显示结果为: 'hello' 

'%s’是输出一个字串,. 默认的输出的被格式化的参数是char * (or const char *). 类型的,可以用'-’表示左对齐的。没有的别的参数,比如:  
printf ("%3s%-6s", "no", "where"); 

显示结果: ' nowhere '. 

  注: 如果你用这个参数来格式化输出一个指针类型的参数时,有可能会得到一个'(null)'的输出值。不过有时候用于指针为空的缘故程序运行时会产生“Segmentation fault”的错误,下面一个例子就会产生这样的错误: 
#include
main()
{ char a;
a = inet_addr("192.168.1.1");
if(a!=-1){
printf("ip:%s",a);/* 这里的%s可能会产生错误,应改用用%p比较好一些*/
}
}


'%m’是输出error信息的。如下例子:  
fprintf (stderr, "can't open '%s': %m", filename); 

等于如下的输出命令: 

fprintf (stderr, "can't open '%s': %s", filename, strerror (errno)); 

“%p”是输出指针类型参数的,显然被格式化的输入参数必须是指针,可以用“-”来表示左对齐的。  
“%n”是比较特殊的参数,它不对格式化输出影响,而是得到输出结果的字符长度,可以用类型指定参数'h' 和 'l'来分别指定输出的参数分别是short int *和 long int *类型的。如下面的例子: 
int nchar; 
printf ("%d %s%n", 3, "bears", &nchar); 

输出结果: 

3 bears 

同时将7的值赋给变量nchar。 

'%%'是输出“
”的字符。

函数具体介绍 

1. printf()函数 

  printf()函数是格式化输出函数系列中比较有具有普遍特点的, 一般用于向标准输出设备按规定格式输出信息。在编写程序时经常会用到此函数。printf()函数的调用格式为: 

  printf("<格式化字符串>;", <参量表>;); 

#include
#include
int main()
{
char c, s[20], *p;
int a=1234, *i;
float f=3.141592653589;
double x=0.12345678987654321;
p="How do you do";
strcpy(s, "Hello, Comrade");
*i=12;
c='x41';
printf("a=%d", a); /*结果输出十进制整数a=1234*/
printf("a=%6d", a); /*结果输出6位十进制数a= 1234*/
printf("a=%06d", a); /*结果输出6位十进制数a=001234*/
printf("a=%2d", a); /*a超过2位, 按实际值输出a=1234*/
printf("*i=%4d", *i); /*输出4位十进制整数*i= 12*/
printf("*i=%-4d", *i); /*输出左对齐4位十进制整数*i=12*/
printf("i=%p", i); /*输出地址i=06E4*/
printf("f=%f", f); /*输出浮点数f=3.141593*/
printf("f=6.4f", f); /*输出6位其中小数点后4位的浮点数f=3.1416*/
printf("x=%lf", x); /*输出长浮点数x=0.123457*/
printf("x=%18.16lf", x);/*输出18位其中小数点后16位的长浮点数x=0.1234567898765432*/
printf("c=%c", c); /*输出字符c=A*/
printf("c=%x", c); /*输出字符的ASCII码值c=41*/
printf("s[]=%s", s); /*输出数组字符串s[]=Hello, Comrade*/
printf("s[]=%6.9s", s);/*输出最多9个字符的字符串s[]=Hello,Co*/
printf("s=%p", s); /*输出数组字符串首字符地址s=FFBE*/
printf("*p=%s", p); /* 输出指针字符串p=How do you do*/
printf("p=%p", p); /*输出指针的值p=0194*/
getch();
retunr 0;
}


  上面结果中的地址值在不同计算机上可能不同。 

  例子中第一条语句#include的含义是调用另一个文件stdio.h, 这是一个头文件, 其中包括全部标准输入输出库函数的数据类型定义和函数说明。对每个库函数便用的变量及函数类型都已作了定义与说明, 放在相应头文件"*.h"中, 用户用到这些函数时必须要用#include<*.h>;或#include"*.h" 语句调用相应的头文件, 以供若没有用此语句说明, 则连接时将会出现错误。 


2  fprintf()函数 

  fprintf( ) 函数中格式化的规定与printf( ) 函数相同, 所不同的只是fprintf()函数是向文件中写入。而printf()是向屏幕输出。 

  下面介绍一个例子, 运行后产后一个test.dat的文件。 


#include
main()
{
char *s="That's good news"}; /*定义字符串指针并初始化*/
int i=617; /*定义整型变量并初始化*/
FILE *fp; /*定义文件指针*/
fp=fopne("test.dat", "w"); /*建立一个文字文件只写*/
fputs("Your score of TOEFLis", fp);/*向所建文件写入一串字符*/
fputc(':', fp); /*向所建文件写冒号:*/
fprintf(fp, "%d", i); /*向所建文件写一整型数*/
fprintf(fp, "%s", s); /*向所建文件写一字符串*/
fclose(fp); /*关闭文件*/
}

  用CAT命令显示TEST.DAT的内容如下所示:屏幕显示 

Your score of TOEFL is: 617 
That's good news 

3 sprintf() 函数 

  sprintf(string, fmt, ...)传回的是string的类型的数组,并以空字符结尾。不过,该函数有可能超过为字符分配的长度。比较危险。下面是一个sprintf()的事例。 

int
//根据传进来的Mission数据结构,建立socket链接,取得文件的大小。
get_size_of_url(struct Mission* pms)
{
int s;
struct sockaddr_in sin;
struct hostent* phe;
char cmd[256];
char msg_hdr[1000];
char* p;
//准备http中GET 方法的请求。
sprintf(cmd,"GET %s HTTP/1.0", pms->;url);
//创建socket
if((s=socket(PF_INET,SOCK_STREAM,0))<0)
return -1;
//取得远程主机的IP地址,失败函数返回-1
if((phe = gethostbyname(pms->;host)) == NULL)
return -1;
memset(&sin,0,sizeof(sin));
memcpy(&sin.sin_addr,phe->;h_addr,sizeof(struct in_addr));
sin.sin_family=AF_INET;
sin.sin_port=htons(pms->;port);
//跟远程机器建立连接,失败函数返回-1
if(connect(s,(struct sockaddr*)&sin,sizeof(sin))==-1)
return -1;
//发送GET请求
if(write(s,cmd,strlen(cmd))<0)
return 0;
//从链接描述符(连接管道)中读取传送过来的数据
if(read(s, msg_hdr, 300)<0)
return 0;
close(s);
printf("%s",msg_hdr);
//读到该文件的大小
if((p=strstr(msg_hdr,"Content-Length"))||(p=strstr(msg_hdr,"Content-length:")))
p+=16;
else
return 0;
//返回大小
return atoi(p);
}

  注:在大部份的Unix系统上,sprintf(string, fmt, ...)传回的是string的指标,然而,这方面Linux(遵循ANSI)传回的却是放入string内的字元数目.进行移植时,尤其是针对SunOS,需有警觉的心。 

4 Snprintf()函数 

  Snprintf()函数与Sprintf()函数极为相似,但是该函数多了size参数来表示最大的字符数目,该函数返回一个整数值表示被存储的字符的数目,如果返回-1则表示输出的字符空间不够。如下例子: 


char *
make_message (char *name, char *value)
{
/* 预分配100个字符空间. */
int size = 100;
char *buffer = (char *) xmalloc (size);
while (1)
{
/* 输出格式化的字符到给定的空间中. */
int nchars = snprintf (buffer, size,"value of %s is %s",name, value);
/* 判断是否返回真值 */
if (nchars < size)
return buffer;
/* 如果空间不够,加大预分配空间到2倍 */
size *= 2;
buffer = (char *) xrealloc (size, buffer);
}
}

5 asprintf()函数 

  int asprintf (char **ptr, const char *template, ...) 

  本函数跟sprintf()函数很类似,只是它将字符串的分配改成动态分配的形式,参数ptr是指一个char *对象的地址函数返回指向一个新建的指针。如下例子: 


/* Construct a message describing the value of a variable whose name is name and whose value is value. */
char *
make_message (char *name, char *value)
{
char *result;
asprintf (&result, "value of %s is %s", name, value);
return result;
}


6 Vprintf()函数 

  int vprintf (const char *template, va_list ap) 

  本函数跟printf函数很类似,只是将参数的数目可变的,变成了一个指针的列表。 

7 Vfprintf()函数 

  int vfprintf (FILE *stream, const char *template, va_list ap) 

  本函数跟fprintf函数很类似,只是将参数的数目可变的,变成了一个指针的列表。 

8 vfprintf()函数 

  int vsprintf (char *s, const char *template, va_list ap) 

  本函数跟sprintf函数很类似,只是将参数的数目可变的,变成了一个指针的列表。 

9 vsnprintf()函数 

  int vsnprintf (char *s, size_t size, const char *template, va_list ap) 

  本函数跟snprintf函数很类似,只是将参数的数目可变的,变成了一个指针的列表。 

10 vasprintf()函数 

  int vasprintf (char **ptr, const char *template, va_list ap) 

  本函数跟asprintf函数很类似,只是将参数的数目可变的,变成了一个指针的列表。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多