有时候需要写不定个数参数的函数。就像c语言的sprintf函数。
函数申明方法是比较固定的:
return-type functionName( [type t1] …)
比如: void fun(…);
: int printf ( const char * format, … );
: 省略号的位置就是不定个数的参数列表了。
接下来,给出常见的3种写法:
比如知道数据是int型。
#include
int sum(int a, ...){
int *temp = &a, sum=0;
++temp;
for (int i = 0; i < a; ++i)
sum+=*temp++;
return sum;
}
int main(){
std::cout<
此方法需借助于c的库函数,目前比较常用的是以下4个函数:
#include
int printf(const char *format, ...); //输出到标准输出
int fprintf(FILE *stream, const char *format, ...); //输出到文件
int sprintf(char *str, const char *format, ...); //输出到字符串str中
int snprintf(char *str, size_t size, const char *format, ...); //按size大小输出到字符串str中,因为长度限制安全些
还有4个不大常用,但实现功能和以上4个一样,不过是使用了参数列表va_list。
#include
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
后4个函数中,va_start()、va_end()、va_arg()就是实现变长的关键了。用法如下(以函数为例):
char s[1000];
int log(char *s, int size, const char *fmt, ...) //该自定义函数,与系统提供的snprintf()函数相同。
{
va_list ap;
int n=0,size=1000;
va_start(ap, fmt); //获得可变参数列表,分析fmt,得出各个参数的类型,也是分析参数中类似”%d%s“的字符串
n=vsnprintf (s, size, fmt, ap); //写入字符串s
va_end(ap); //释放资源,必须与va_start成对调用
return n; //返回写入的字符个数
}
方法2已经比较实用,但毕竟以c的函数为主,处理不当时可能会出现数据溢出,不易查找错误。这时可以考虑Boost::format,这是Boost的一个功能库,专门格式化字符串,如果出错会抛出异常。Boost.Format是一个类,它的可扩展性还是不错的,但效率比起sprintf还是要差不少的。
用法如下:
#include
#include
#include
using namespace std;
using namespace boost;
int main(){
// 使用%序号%的方式给出指示符,后面用%连接对应的数据。
cout<
boost.format指定格式的方式为:
形式为:[ N$ ] [ flags ] [ width ] [ . precision ] type-char
另外,boost.format有一个方便的用法%N%,如文中第一个示例。
boost.format抛出的异常有bad_format_string、too_few_args、too_many_args、out_of_range等。