首页 > 编程知识 正文

c++ snprintf,vsnprintf和snprintf

时间:2023-05-04 17:57:12 阅读:259285 作者:780

函数定义:

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

函数说明:

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

函数返回值:

若成功则返回欲写入的字符串长度,若出错则返回负值。返回值并不是真正写入字符串的大小。

解释如下:
size是限定最终生成的dest的字符数,最多拷贝size-1个字符; 一般情况下size会取sizeof(dest),这是为了dst不溢出.

在snprintf(dest, size, "str: %sn", src)中如果size-1大于等于"str: %sn"的长度,则把"str: %sn"都拷贝到dst; 如果size-1小于"str: %sn"的长度,则从"str: %sn"拷贝size-1长度的字符串到dst,并且末尾置.

就是说,拷贝的长度是size-1和源字符串长度的最小值;

错误使用snprintf函数返回值

代码示例

int main() { char buf[10] = ""; char src[30] = "hello world! hello world!"; int len = snprintf(buf, sizeof(buf), "%s", src); printf("return len=%dn", len); buf[len] = ''; printf("buf=%s, bufLen=%dn", buf, strlen(buf)); return 0; }

现象&后果

上述代码运行时返回的len是25,写buf[len]=''时将出现错误。

Bug分析

snprintf函数返回的是预写入的字符串长度。以上述代码为例,如果源字符串src的长度小于等于sizeof(buf)-1,返回值则为实际写入目标字符串buf的字符数,也就是src的长度;如果src的长度大于sizeof(buf)-1,实际写入buf的字符数为sizeof(buf)-1,但返回值依然为src的长度。但snprintf返回值不一定就是src的长度,例如,当格式化字符串包含其他字符时,如上面的"%s"改为"ab=%s",返回值就比src的长度要大。实际上snprintf返回值可以理解为当buf大小没有限制时写到buf的字符个数。

在例子中len=25,buf[25]=''产生写越界,从而产生段错误,可能导致重大问题。上述代码实际上是想在snprintf复制完之后显式地在buf结尾处添加一个''。但实际上,snprintf函数在复制结束时自动就会处理字符串结束标志''的问题,不用额外处理。

snprintf函数的返回值常被用来和目标字符串buf的大小进行比较,以判断此次复制是否完全。

int main() { char buf[10] = ""; char src[30] = "hello world! hello world!"; int len = snprintf(buf, sizeof(buf), "%s", src); printf("return len=%dn", len); if(len>sizeof(buf)-1) { printf("[Error] Source string length is %d. The buf size %d is not enough. Copy incomplete!n", len, sizeof(buf)); }else{ printf("buf=%s, bufLen=%dn", buf, strlen(buf)); } return 0; }

其实主要有两点:

1.函数返回值并不是实际写入字符串的大小,是欲要写入字符串的大小。

2.此函数会自动在字符串末尾补0,不需要再额外添加

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。