最近,编写一个程序需要将两个字符串连接起来,我使用了sprintf函数,总是出现错误的结果。后来,把结果打印出来,才发现原来是char指针中有空字符(ASCII码为0的字符)。我的错误代码如下:
unsigned char szbuffer[1024];
unsigned char head[10]={0xFF,0xFF,0x01,0x01,0x06,0x01,0x00,0x00,0x00,0x00};
char * sfile="<FILE_LOCATION_REQ><FILE_ID>4567FEDC4567FEDC4567FEDC4567FEDC4567FEDC4567FEDC</FILE_ID></FILE_LOCATION_REQ>";
sprintf((char *)szbuffer,"%.10s%s",head,sfile);
结果,总是不能连接成功,后来又尝试使用strcat函数,将两个字符串连接:代码如下:
szbuffer[i]=head[i];
strcat((char *)szbuffer,sfile);
后来,我才发现,原来是head中有ASCII码值为0的字符,而这个字符,在字符串中是字符串的结束符号。所以,是用sprintf和strcat时,遇到0x00字符串都会结束。我又找了一下别人使用sprintf的总结,放在下面:
以下为我在编程的过程中用到sprintf,后查找资料及自己的一些总结。感谢网上资料的帮助。
在很多场合可以使用sprintf来实现类型转换,
int sprintf( char *buffer, const char *format [, argument] ... );
除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数.
比如
1. const char* 转换成char*
有时我们需要把string类型的字符串转换成char*,但是string.c_str()等到的结果是const char*类型而不是char*类型,转换方法就是先把string转换成const char*,然后用sprintf把const char*转换成char*
如:string str;
char* strchar;
const char* strC = str.c_str();
sprintf(strchar,"%s",str.c_str());
2.将int类型转换成char*
//把整数123 打印成一个字符串保存在s 中。
sprintf(s, "%d", 123); //产生"123"
3.将浮点数转换成char*
但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m.nf”格式,其中m 表示打印的宽度,n 表示小数点后的位数。比如:
sprintf(s, "%10.3f", 3.1415626); //产生:" 3.142"
4.实现字符串的连接
char* who = "I";
char* whom = "CSDN";
sprintf(s, "%s love %s.", who, whom); //产生:"I love CSDN. "
使用sprintf 的常见问题
sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访问错误,但好在由sprintf 误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通常用眼睛再把出错的代码多看几眼就看出来了。
1 缓冲区溢出
1 缓冲区溢出
第一个参数的长度太短了,没的说,给个大点的地方吧。当然也可能是后面的参数的问题,建议变参对应一定要细心,而打印字符串时,尽量使用”%.ns”的形式指定最大字符数。
2. 忘记了第一个参数低级得不能再低级问题,用printf 用得太惯了。
2. 忘记了第一个参数低级得不能再低级问题,用printf 用得太惯了。
3. 变参对应出问题通常是忘记了提供对应某个格式符的变参,导致以后的参数统统错位,检查检查吧。尤其是对应”*”的那些参数,都提供了吗?不要把一个整数对应一个”%s”.