C++ 不定个数参数写法
2016-01-23 22:28
387 查看
有时候需要写不定个数参数的函数。就像c语言的sprintf函数。
函数申明方法是比较固定的:
return-type functionName( [type t1] …)
比如: void fun(…);
int printf ( const char * format, … );
省略号的位置就是不定个数的参数列表了。
接下来,给出常见的3种写法:
方法1知道数据的具体类型时
方法2使用va_startva_endva_arg和vsnprintf
方法3使用Boostformat
还有4个不大常用,但实现功能和以上4个一样,不过是使用了参数列表va_list。
后4个函数中,va_start()、va_end()、va_arg()就是实现变长的关键了。用法如下(以函数为例):
用法如下:
boost.format指定格式的方式为:
形式为:[ N$ ] [ flags ] [ width ] [ . precision ] type-char
其中:N$用于指定第N个参数,但这个参数要么都加,要么都不加
flags用于处理格式,比如对齐。
width指当前给出宽度
.precision小数点后多少位
type-char指数据类型(与sprintf相同)
另外,boost.format有一个方便的用法%N%,如文中第一个示例。
boost.format抛出的异常有bad_format_string、too_few_args、too_many_args、out_of_range等。
函数申明方法是比较固定的:
return-type functionName( [type t1] …)
比如: void fun(…);
int printf ( const char * format, … );
省略号的位置就是不定个数的参数列表了。
接下来,给出常见的3种写法:
方法1知道数据的具体类型时
方法2使用va_startva_endva_arg和vsnprintf
方法3使用Boostformat
方法1:知道数据的具体类型时
比如知道数据是int型。#include<iosteam> void sum(int a, ...){ int *temp = &a, sum=0; ++temp; for (int i = 0; i < a; ++i) sum+=*temp++; } int main(){ std::cout<<sum(4, 1, 2, 3, 4)<<std::endl; return 0; }
方法2:使用va_start()、va_end()、va_arg()和vsnprintf()
此方法需借助于c的库函数,目前比较常用的是以下4个函数:#include <stdarg.h> 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 <stdarg.h> 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; //返回写入的字符个数 }
方法3:使用Boost::format
方法2已经比较实用,但毕竟以c的函数为主,处理不当时可能会出现数据溢出,不易查找错误。这时可以考虑Boost::format,这是Boost的一个功能库,专门格式化字符串,如果出错会抛出异常。Boost.Format是一个类,它的可扩展性还是不错的,但效率比起sprintf还是要差不少的。用法如下:
#include <boost/format.hpp> #include <iostream> #include <string> using namespace std; using namespace boost; int main(){ // 使用%序号%的方式给出指示符,后面用%连接对应的数据。 cout<<format("%1%=%2%")%"x"%1.1<<endl; // 输出:x=1.1 // 可以延迟使用,顺序不必一致,而且可重用 boost::format fmter("%2% %1%"); fmter % 21; fmter % 20; cout << fmter << endl; // 输出: 20 21 // 可直接转成字符串 string s = fmter.str(); // 可以使用printf指示符 cout<<format("%.2f-%s")%5.1%"abc"<< endl; // 输出:5.10-abc // printf指示符里使用N$指定使用第几个参数 cout<<format("%2$.2f-%1$s%") %5.1%"abc"<< endl; // 输出:5.10-abc }
boost.format指定格式的方式为:
形式为:[ N$ ] [ flags ] [ width ] [ . precision ] type-char
其中:N$用于指定第N个参数,但这个参数要么都加,要么都不加
flags用于处理格式,比如对齐。
width指当前给出宽度
.precision小数点后多少位
type-char指数据类型(与sprintf相同)
另外,boost.format有一个方便的用法%N%,如文中第一个示例。
boost.format抛出的异常有bad_format_string、too_few_args、too_many_args、out_of_range等。
相关文章推荐
- c++ 中 BOOL与bool TRUE与true FALSE与false 区别 (转载)
- C和C++中三目运算符对比
- 几种素数的判定方法
- utilities(C/C++)
- C++类静态成员初始化
- 小蚂蚁学习C语言(35)——两行三列二维数组变三行两列二维数组
- 常见算法:C语言求最小公倍数和最大公约数三种算法
- C语言 hdoj1002
- C/C++中volatile关键字详解
- c++的那些坑--运算符优先级
- 全局变量引发的链接时的LNK2005xxx already defined in yyyy.obj
- c++中类对象分配内存大小与虚继承的一些问题
- 【C语言】写一个函数,实现字符串内单词逆序
- 用VLFeat库进行SIFT特征提取(C++ 实现)
- 1023. Have Fun with Numbers (20)
- HDU-1032-The 3n + 1 problem(C++&学英语&水题)
- c++企业级接口框架(二)
- 库函数的认识及 C/C++常用 api 及基本库
- 1084. Broken Keyboard (20)
- GCC 下 tranform 调用 toupper, tolower 出错原因及解决