详细介绍snprintf与vsnprintf函数的区别

文章详细介绍了C语言中的snprintf和vsnprintf函数,包括它们的函数原型、功能、参数以及返回值的特性。snprintf函数将格式化的可变参数写入字符串,返回值不包含末尾的但可能包含转义字符。vsnprintf与snprintf类似,但使用va_list处理可变参数,更灵活。在示例中展示了当限制字符串长度时,函数如何处理超过限制的字符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

snprintf函数详细介绍以及实例

vsnprinf函数详细介绍以及实例

 结论


snprintf函数

函数原型:int snprintf(char *str, size_t size, const char *format, ...)

函数功能:将可变参数按照 format格式化成字符串,并将字符串复制到 str 中

str:目标字符串
size:写入字符的个数   注意:算\0,算format里面的转义系列字符
format:格式化字符串   

变参:要与format对应

返回值: 返回要写入的字符串长度,不管str(目标字符串)的大小 

注意:此返回值长度不包括字符串末尾的\0,但如果format中有\n\t等转义系列字符,则返回值将会将其计算在内

例程:

#include <stdio.h>
 
int main()
{
    char buffer[50];
	int b = 20;
	char* n = "abc";
	char* m = "def";
    // 读取字符串并存储在 buffer 中
    int j = snprintf(buffer, 8, "%s\n%s\n", n,m);
    // 输出 buffer及字符数
    printf("string:%s character count = %d\n", buffer, j);
 
    return 0;
}

 运行结果

 

由此可以看出返回值会将\n计算在内,但不计算字符串末尾\0,只输出到了f,但没输出最后的\n,说明size算字符串末尾\0。

还有一个问题,接下来再看这个历程:

#include <stdio.h>
 
int main()
{
    char buffer[50];
	int b = 20;
	char* n = "abc";
	char* m = "def";
	char* p = "ghi";
    // 读取字符串并存储在 buffer 中
    int j = snprintf(buffer, 9, "%s%s%s\n", n,m,p);
    // 输出 buffer及字符数
    printf("string:%s character count = %d\n", buffer, j);
 
    return 0;
}

运行结果 

 

 我明明设置了最大限制为9个字符,为什么输出到了h?前面得出的结论是size是算字符串末尾的\0也算转义系列字符的,但这个结果与其不符。

原来snprintf函数将可变参数复制到str中时,只有两个字符串在一起(若被转义字符分开还是正常),会忽视其字符串末尾的\0,在转换完成后再在转换后的字符串后面加上一个\0,这样就符合上面例程的结果。并且,如果转换的是int或者其他类型,该函数也会将他们一位一位看作一个字符进行输出。

vsnprinf函数

函数原型:int vsnprintf (char * sbuf, size_t n, const char * format, va_list arg )

函数功能:向一个字符串缓冲区打印格式化字符串使用

sbuf:一个数组,用于缓存格式化字符串结果的数组
n:限定打印最多n-1个(此函数还会在结果末尾增加\0)
format:格式化限定字符串要格式化的字符串,里面的%符都会被转化为对应的arg
arg:可变长度参数列表
返回值:成功打印到subf数组的字符个数不包括末尾追加的\0

#include <stdio.h>
#include <string.h>
#include <stdarg.h> 
#define SBUF_SIZE 128
char sbuf[SBUF_SIZE];
void MyPrintF( const char * format, ... )
{
	va_list args;
	va_start (args, format);
	vsnprintf (sbuf,SBUF_SIZE,format, args);
	va_end (args);
	printf("%s",sbuf);		
}
int main()
{	
	MyPrintF("my name is %s,my age is %d\n","bob",18);
    	return 0;
}

运行结果 

让我们来实验一下这个函数的返回值,以及size的特性是否跟上面的snprintf一样

#include <stdio.h>
#include <string.h>
#include <stdarg.h> 
#define SBUF_SIZE 128
char sbuf[SBUF_SIZE];
void MyPrintF( const char * format, ... )
{
	va_list args;
	va_start (args, format);
	vsnprintf (sbuf,16,format, args);
	va_end (args);
	printf("%s",sbuf);		
}
int main()
{	
	MyPrintF("name:%s\n,age:%d\n","bob",18);
    	return 0;
}

我将size限制成了16,如果沿用snprintf的特性,这个结果与其完全符合。

 结论

 vsnprintf与snprintf其内部的特性完全一致,无论是返回值还是size的计算方式,在细节上大相径庭,但是vsnprintf的可变参数需要的一个va_list类型的变量,个人感觉会更加灵活一些。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值