C中snprintf与vsnprintf函数

虽然snprintf函数在开发过程中比较常用,但是其中有一些细节性的问题需要注意。因为snprintf函数不是C中的标准函数,不同的编译器可能对该函数的实现不同,本文说明是基于GCC编译器。

snprintf函数

函数原型

snprintf函数的作用是将格式化的数据写入字符串。其函数原型如下:

1
snprintf(char* buffer, int n, char* format, ...);

参数说明

  • buffer : 存储格式化字符串的buffer
  • n : 指定格式化字符串的大小,包括\0
  • format : 指定需要格式化字符串的format
  • … : 可变参数

返回值

该函数的返回值为其期望字符串的长度,而不是实际存入buffer中的字符串的长度。且不包括\0

注意点

特别注意函数原型中的第二个参数包括\0的大小,而返回值为期望大小且不包括\0。

例:

1
2
3
4
5
6
7
8
char buffer[256];
//返回值ret = 13,buffer中的内容为123456789
int ret = snprintf(buffer, 10, "%s", "1234567890abc");
memset(buffer, 0x0, sizeof(buffer));
//返回值ret = 3,buffer中的内容为123
ret =snprintf(buffer, 10, "%s", "123");

snprintf与vsnprintf

snprintf和vsnprintf都是C语言printf家族函数的成员。实际上,snprintf和vsnprintf功能完全一样,只是vsnprintf将snprintf中的可变参数换成了av_list类型。如下:

1
2
3
4
5
#include <stdio.h>
int printf(const char* format, ...); //输出到标准输出
int fprintf(FILE* stream, const char* format, ...); //输出到文件
int sprintf(char* buffer, const char* format, ...); //输出到字符串
int snprintf(char* buffer, int n, const char* format, ...); //输出到字符串
1
2
3
4
5
#include <stdarg.h>
int vprintf(const char* format, va_list ap); //输出到标准输出
int vfprintf(FILE* stream, const char* format, va_list ap); //输出到文件
int vsprintf(char* buffer, const char* format, va_list ap); //输出到字符串
int vsnprintf(char* buffer, int n, const char* format, va_list ap); //输出到字符串

va_list获取

可变参数va_list获取方式通过下列函数获取,并且总是成对调用

1
2
va_start(va_list ap, last);
va_end(va_list ap);

简单的使用vsnprintf函数实现snprintf

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <stdarg.h>
int my_snprintf(char* buffer, int size, const char* format, ...) {
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buffer, size, format, ap);
va_end(ap);
return ret;
}