1、sprintf
字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。
原型
int sprintf( char *buffer, const char *format, [ argument] … );
参数列表
buffer:
char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]..
.:可选参数,可以是任何类型的数据。
返回值:字符串长度(
strlen)
/*例子*/
|
1
2
3
4
5
6
7
8
9
10
11
|
#include<stdio.h>//某个头文件
intmain()
/*主函数“整数”类型*/
{
charbuffer[50];
/*“字符”类型的数组,下面共有50个元素。*/
intn,a=5,b=3;
/*三个变量都为“整数”类型,intn中间要有空格*/
n=
sprintf
(buffer,
"%dplus%dis%d"
,a,b,a+b);
/*赋予数值*/
printf
(
"[%s]isastring%dcharslong\n"
,buffer,n);
/*“格式输出”*/
return0;
/*“返回零”
也就是程序正常退出*/
}
|
输出结果:
[5 plus 3 is 8] is a string 13 chars long
|
sprintf格式的规格如下所示。[]中的部分是可选的。
%[指定参数][
标识符][宽度][.精度]指示符
若想输出'%'本身时, 请使用'%%'处理。
1. 处理字符方向。负号时表示从后向前处理。
2. 填空字元。 0 的话表示空格填 0;空格是内定值,表示空格就放着。
3.
字符总宽度。为最小宽度。
4. 精确度。指在小数点后的浮点数位数。
%% 印出百分比符号,不转换。
%c 整数转成对应的 ASCII 字元。
%d 整数转成十进位。
%f 倍精确度数字转成浮点数。
%o 整数转成八进位。
%s 整数转成字符串。
%x 整数转成小写十六进位。
%X 整数转成大写十六进位。
$money = 123.1
$formatted = sprintf ("%06.2f", $money); // 此时变数 $ formatted 值为 "123.10"
$formatted = sprintf ("%08.2f", $money); // 此时变数 $ formatted 值为 "00123.10"
$formatted = sprintf ("%-08.2f", $money); // 此时变数 $ formatted 值为 "123.1000"
$formatted = sprintf ("%.2f%%", 0.95 * 100); // 格式化为百分比
举例子:
1、sprintf(s, "%d", 123);
//产生"123"
//把整数123 打印成一个字符串保存在s 中。
所以,sprintf 在大多数场合可以替代
3、sprintf(s, "%-4d%4d", 123, 4567);
itoa。
2、sprintf(s, "%4d%4d", 123, 4567);
//产生:" 1234567"可以指定宽度,不足的左边补空格:
//产生:"123 4567"
4、sprintf(s, "%f", 3.1415926);
//产生"3.141593" %f,默认保留小数点后6 位数字
char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};
如果:
sprintf(s, "%s%s", a1, a2); //Don't do that!
十有八九要出问题了。是否可以改成:
sprintf(s, "%7s%7s", a1, a2);
也没好到哪儿去,正确的应该是:
sprintf(s, "%.7s%.7s", a1, a2);//产生:"ABCDEFGHIJKLMN"
这可以类比打印浮点数的”%m/nf”,在”%m.ns”中,m 表示占用宽度(
字符串长度不足时补空格,超出了则按照实际宽度打印),n 才表示从相应的字符串中最多取用的字符数。通常在打印字符串时m 没什么大用,还是点号后面的n 用的多。自然,也可以前后都只取部分
字符:
sprintf(s, "%.6s%.5s", a1, a2);//产生:"ABCDEFHIJKL"
在许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的,而不是静态指定的,因为许多时候,程序要到运行时才会清楚到底需要取
字符
数组中的几个字符,这种动态的宽度/精度设置功能在sprintf 的实现中也被考虑到了,sprintf 采用”*”来占用一个本来需要一个指定宽度或精度的常数数字的位置,同样,而实际的宽度或精度就可以和其它被打印的
变量一样被提供出来,于是,上面的例子可以变成:
sprintf(s, "%.*s%.*s", 7, a1, 7, a2);
或者:
sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
1
2
3
|
sprintf
(s,
"%-*d"
,4,
'A'
);
//产生"65"
sprintf
(s,
"%#0*X"
,8,128);
//产生"0X000080","#"产生0X
sprintf
(s,
"%*.*f"
,10,2,3.1415926);
//产生"3.14"
|
打印地址信息
1
|
sprintf
(s,
"%u"
,&i);
|
不过通常人们还是喜欢使用16 进制而不是10 进制来显示一个地址:
1
|
sprintf
(s,
"%08X"
,&i);
|
然而,这些都是间接的方法,对于地址打印,sprintf 提供了专门的”%p”:
1
|
sprintf
(s,
"%p"
,&i);
|
我觉得它实际上就相当于:
1
|
sprintf
(s,
"%0*x"
,2*
sizeof
(
void
*),&i);
最后:
|
sprintf_s和snprintf
sprintf_s()是sprintf()的安全版本,通过指定
缓冲区长度来避免sprintf()存在的溢出风险 。在使用VS2008时如果你使用了sprintf函数,那么
编译器会发出警告:使用sprintf存在风险,建议使用
sprintf_s。这个安全版本的原型是:
int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format [,argument] ... );
不过sprintf_s()是微软私有的函数,考虑到跨平台移植,最好使用snprintf()。两者的原型基本相同:
int _snprintf(char *buffer, size_t count, const char *format [,argument] ... );