snprintf()函数使用方法

众所周知,sprintf不能检查目标字符串的长度,可能造成众多安全问题,所以都会推荐使用snprintf.
自从snprintf代替了sprintf,相信大家对snprintf的使用都不会少,函数定义如下:

int snprintf(char*str, size_t size,constchar*format, ...);

函数说明:最多从源串中拷贝size-1字符到目标串中,然后再在后面加一个 \0 。所以如果目标串的大小为size的话,将不会溢出。

函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。

Result1(推荐的用法)

#include <stdio.h>
#include <stdlib.h>

int main()
{
     char str[10]={0};

     snprintf(str, sizeof(str), "0123456789012345678");

     printf("str=%s\r\n", str);
     return 0;
}
root] /root/lindatest
$ ./test
str=012345678

Result2:(不推荐使用)


#include <stdio.h>
#include <stdlib.h>
int main()
{
    char str[10]={0};
    snprintf(str, 18, "0123456789012345678");
    printf("str=%s\r\n", str);
    return 0;
}
root] /root/lindatest
$ ./test
str=01234567890123456

情形一】:源串小于目标字符串

实际上源串为:"123\0",所以只将字符'1','2','3', '\0'拷到了目标串,返回值为源串的strlen为3

#include <stdio.h>
#include <strings.h>
#include <string.h>
int main(void)
{
	char a[10] = {'\0'};
	int i = 0;
	int ret = 0;
	memset(a, 0, sizeof(a));
	for(i = 0; i < 10; i++) {
		printf("a[%d] = %d\n",i,a[i]);
	}

	ret = snprintf(a, 10, "%d", 123);
	printf("ret = %d\n",ret);

	for(i = 0; i < 10; i++) {
		printf("a[%d] = %d\n",i,a[i]);
	}
	return 0;
}
a[0] = 0
a[1] = 0
a[2] = 0
a[3] = 0
a[4] = 0
a[5] = 0
a[6] = 0
a[7] = 0
a[8] = 0
a[9] = 0
ret = 3
a[0] = 49
a[1] = 50
a[2] = 51
a[3] = 0
a[4] = 0
a[5] = 0
a[6] = 0
a[7] = 0
a[8] = 0
a[9] = 0

--------------------------------
Process exited after 0.1323 seconds with return value 0
请按任意键继续. . .

情形二】:源串等于目标字符串

源串为"abcdefghi\0",正好将源串拷贝到目标字符串中,返回值为源串的strlen为9

#include <stdio.h>
#include <strings.h>
#include <string.h>
int main(void)
{
	char a[10] = {'\0'};
	int i = 0;
	int ret = 0;
	memset(a, 0, sizeof(a));
	for(i = 0; i < 10; i++) {
		printf("a[%d] = %d\n",i,a[i]);
	}

	ret = snprintf(a, 10, "%s","abcdefghi");
	printf("ret = %d\n",ret);

	for(i = 0; i < 10; i++) {
		printf("a[%d] = %d\n",i,a[i]);
	}
	return 0;
}
a[0] = 0
a[1] = 0
a[2] = 0
a[3] = 0
a[4] = 0
a[5] = 0
a[6] = 0
a[7] = 0
a[8] = 0
a[9] = 0
ret = 9
a[0] = 97
a[1] = 98
a[2] = 99
a[3] = 100
a[4] = 101
a[5] = 102
a[6] = 103
a[7] = 104
a[8] = 105
a[9] = 0

--------------------------------
Process exited after 0.3018 seconds with return value 0
请按任意键继续. . .

情形三】源串大于目标字符串

源串为"abcdefghijklmnopq\0",最多从源串拷贝10个字节(含\0)到目标串那么就是拷贝源串的9个字节内容(abcdefghi)再加一个\0到目标串,目标串的结果和情形二一样,但是ret返回值变成了17,即strlen("abcdefghijklmnopq")

#include <stdio.h>
#include <strings.h>
#include <string.h>
int main(void)
{
	char a[10] = {'\0'};
	int i = 0;
	int ret = 0;
	memset(a, 0, sizeof(a));
	for(i = 0; i < 10; i++) {
		printf("a[%d] = %d\n",i,a[i]);
	}

	ret = snprintf(a, 10, "%s", "abcdefghijklmnopq");
	printf("ret = %d\n",ret);

	for(i = 0; i < 10; i++) {
		printf("a[%d] = %d\n",i,a[i]);
	}
	return 0;
}

在VC中编译如下程序:

a[0] = 0
a[1] = 0
a[2] = 0
a[3] = 0
a[4] = 0
a[5] = 0
a[6] = 0
a[7] = 0
a[8] = 0
a[9] = 0
ret = -1
a[0] = 97
a[1] = 98
a[2] = 99
a[3] = 100
a[4] = 101
a[5] = 102
a[6] = 103
a[7] = 104
a[8] = 105
a[9] = 106

--------------------------------
Process exited after 0.02983 seconds with return value 0
请按任意键继续. . .

在GCC中编译如下程序:

a[0] = 0
a[1] = 0
a[2] = 0
a[3] = 0
a[4] = 0
a[5] = 0
a[6] = 0
a[7] = 0
a[8] = 0
a[9] = 0
ret = 17
a[0] = 97
a[1] = 98
a[2] = 99
a[3] = 100
a[4] = 101
a[5] = 102
a[6] = 103
a[7] = 104
a[8] = 105
a[9] = 106

--------------------------------
Process exited after 0.02983 seconds with return value 0
请按任意键继续. . .

snprintf打印16进制

snprintf(temp, sizeof temp, "%X", USART_RX_BUF[0]);

%02x     格式控制: 以十六进制输出,2为指定的输出字段的宽度.如果位数小于2,则左端补0

 如果USART_RX_BUF[0]里的数据是0xf8,

snprintf(temp, sizeof temp, "%X", USART_RX_BUF[0]);

temp[0]的值为0x46;
temp[1]的值为0x38;

参考:https://blog.csdn.net/liaojunwu/article/details/80489406

参考:https://blog.csdn.net/sky1203850702/article/details/52778831

参考:https://blog.csdn.net/shenhuxi_yu/article/details/70195133

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值