函数调用形式:
int sprintf(char *string,char *format,arg_list);
函数功能:
将一个格式化的字符串(format)输出到一个目的字符串中(string),而printf是将一个格式化的字符串输出到屏幕。注意二者的区别。
1.连接字符串
char s[100]; char *who="I"; char *whom="CSDN"; sprintf(s,"%s love %s",who,whom);
strcat 只能连接字符串,但有时我们有两段字符缓冲区,他们并不是以’’结尾。比如许多从第三方库函数中返回的字符数组,从硬件或者网络传输中读进来的字符流,它们未必每一段字符序列后面都有个相应的’’来结尾。如果直接连接,不管是sprintf 还是strcat 肯定会导致非法内存 *** 作,那该怎么办呢?我们自然会想起前面介绍打印整数和浮点数时可以指定宽度,字符串也一样的。
char a1[]={'A','B','C','D','E','F','G'}; char a2[]={'H','I','J','K','L','M','N'}; sprintf(s,"%s%s",a1,a2);
完了,全乱了,哎。。。。。。。。要不试一试下面这种 *** 作???
char a1[]={'A','B','C','D','E','F','G'}; char a2[]={'H','I','J','K','L','M','N'}; sprintf(s,"%7s%7s",a1,a2);
给它机会,它也不中用啊。。。。。。要不再试一下下面这种 *** 作???
char a1[]={'A','B','C','D','E','F','G'}; char a2[]={'H','I','J','K','L','M','N'}; sprintf(s,"%.7s%.7s",a1,a2);
字符数组a1和a2终于完成了神圣的结合,cheers
这可以类比打印浮点数的"%m.nf",在"%m.ns"中,m表示占用宽度(字符串长度不足时补空格,超出了则按照实际宽度打印),n才表示从相应的字符串中最多取用的字符数。通常在打印字符串时m没什么卵用,还是点号后面的n用的多。当然也可以前后只取部分字符:
sprintf(s,"%.6s%.5s",a1,a2);
在许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的,而不是静态指定的,因为许多时候,程序要到运行时才会清楚到底需要取字符数组中的几个字符,这种动态的宽度/精度设置功能在sprintf的实现中也被考虑到了。sprintf采用"*"来占用一个本来需要一个指定宽度或精度的常数数字的位置。同样,而实际的宽度或精度就可以和其它被打印的变量一样被提供出来。于是,上面的例子可以变成:
char a1[]={'A','B','C','D','E','F','G'}; char a2[]={'H','I','J','K','L','M','N'}; sprintf(buffer, "%.*s%.*s", 7, a1, 7, a2); sprintf(buffer, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
2.打印地址
sprintf(s,"%p",&i);
sprintf函数使用注意事项
1.空间分配问题
C语言在进行字符串 *** 作时不检查字符串的空间是否够大,所以可能会出现数组越界而导致程序崩溃的问题。即使碰巧,程序没有出错,也不要这么用,因为早晚会出错。所以,一定要在调用之前分配足够大的空间给string。
2.符号扩展问题
打印短整数(short)-1的内存十六进制表示形式,在Win32平台上,一个short型数占两个字节,所以我们自然希望用4个十六进制数字来打印它。
short si=-1; sprintf(s,"%04X",si);
产生FFFFFFFF,怎么回事?因为sprintf函数是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的。函数更没有办法仅仅通过一个%X就能得知当初函数调用前参数压栈时被压进来的到底是个4字节的整数还是个2字节的短整数,所以采取了统一4字节的处理方式,导致参数压栈时做了符号扩展,扩展成了32位的整数-1,打印时4个位置不够了,就把32位整数-1的8位十六进制都打印出来了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)