snprintf总结

一、函数概要
snprintf函数是sprintf函数的安全版本,因为它在调用的时候需要指定缓冲区的最大尺寸,这样可以有效避免缓冲区的益处。
如果写入的字符串尺寸大于size-1,那么后边的字符串将被丢弃,但是依旧会统计进长度中(返回值)。
format参数后边的额外参数数量是由format决定的,具体用法请参考printf函数中格式化占位符的解释。


将可变个参数(...)按照format格式化成字符串,然后将其复制到str中 

(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0'); 
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0') 

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

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

二、函数原型

#include<stdio.h>
int snprintf(char *str, size_t size, const char *format, ...);

三、参数解析


参数含义
str指向存放结果字符串的缓冲区
size 1.限定缓冲区最大可写入的字节数
2.字符串最多可以拥有size-1 个字符串,最后一个空位用于存放‘\0'
3.size_t 被定义为无符号整型
format格式化字符串
... 可选参数,具体请参考printf函数文档

四、返回值
 如果指定size的缓冲区足够存放写入的字符,返回值是实际写入的字符数(不包含表示字符串结束的‘\0’);
 如果函数调用失败,返回值是一个负数。


五、功能  :合并字符串、整形变量转换成字符串
(1)将数字变量转换为字符串。
(2)得到整型变量的16进制和8进制字符串。
(3)连接多个字符串。


六、注意

1.试图写入字符的数量超过size,并不会导致错误发生,只是超过部分被丢弃。

2.只有当返回值小于size 且非负数,才证明字符串被完全写入。

举例:

1、整型数字转换为字符串

#include<stdio.h>
int main()
{
        char testdstchar[10]={0};
        int j = 12;
        snprintf(testdstchar,sizeof(testdstchar), "%d", j);
        printf("%s",testdstchar);
        return 0;
}

输出:12

2、浮点型转换为字符串

#include<cstdio>  
#include<string>  
#include<iostream>  
using namespace std;  
  
int main() {  
    char a[10];  
    double i = 12.532423;  
    snprintf(a, sizeof(a), "%lf", i);      
    cout << a << endl;  
    snprintf(a, sizeof(a), "%0.2lf", i); //设置转换的精度  
    cout << a << endl;  
}  

输出结果为:

12.532423
12.53


3、拷贝字符串

#include<cstdio>  
#include<string>  
#include<iostream>  
using namespace std;  
  
int main() {  
    char a[10];  
    char c[] = "dskcdsvkjgch";  
    snprintf(a, sizeof(a), "%s", c);    //以a的数组长度作为转换的位数,则最多拷贝9为,最后加\0。  
    cout << a << endl;                
    snprintf(a, sizeof(c), "%s", c);    //以c的字符长度作为转换的位数,系统会自动将a的数组长度调整到刚好能匹配c的字符。  
    cout << a << endl;    
}  

输出结果:

dskcdsvkj

dskcdsvkjgch


使用snprintf的另一个好处是可以实现字符串的连接,再加上其相对安全的功能,strcat基本就可以抛弃了

#include<cstdio>  
#include<string>  
#include<iostream>  
using namespace std;  
  
int main() {  
    char a[10];  
    char c[] = "dskc";  
    snprintf(a, sizeof(a), "%s", c);  //以数组名作为参数,实际上是从数组 第一位开始拷贝字符。  
    cout << a << endl;  
    snprintf(a+4, sizeof(a), "%s", c);  //实现连接,要注意连接开始的位置,之前a的前四位有字符,因此从第五位开始,对应数组脚标4,小于4,则之前的字符被覆盖,大于4,则a[4]为'\0';  
    cout << a << endl;    
}  
输出结果:

dskc

dskcdskc


需要注意的几点:

1、函数的返回值

snprintf的返回值是欲写入的字符串长度,而不是实际写入的字符串度。

#include<stdio.h>

int main()
{
        char testdstchar[10]={0};
        int j = 12;
        int ret = 0;
        ret = snprintf(testdstchar, 5,"123456789");
        printf("%d|%s",ret,testdstchar);
        return 0;
}

输出: 9|1234  

#include<stdio.h>

int main()
{

        char testdstchar[10]={0};
        int j = 12;
        int ret = 0;
        ret = snprintf(testdstchar, 11,"12345678901234567890");

        printf("%d|%s",ret,testdstchar);
        return 0;
}

输出:20|1234567890


2、利用snprintf函数来提前获取需要的内存空间大小.

按如下格式调用:int ret = snprintf(NULL,0,"%s%d","test", 123); //结果ret为7   
即设置第一二个参数分别为NULL和0,获得的ret就为实际需要的内存空间大小。这对于打印长度不可预知的字符串比较有效,便于我们合理分配空间,既不浪费又不产生截断。   

(1)如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束('\0');   

(2)如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0') 

3、snprintf处理原始和目标缓冲区重叠时,会出现不可预期的结果。

#include<stdio.h>

int main()
{

        char testdstchar[10]="abcdefg";
        int j = 12;
        int ret = 0;
        ret = snprintf(testdstchar, 10,"%s,hello",testdstchar);

        printf("%d|%s",ret,testdstchar);
        return 0;
}

输出:6|,hello

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值