使用va_list+_vsnprintf处理不定参数
首先感觉这段代码挺实用的:
INTSIZEOF 宏,获取类型占用的空间长度,最小占用长度为int的整数倍:
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) //这个技巧常用到
VA_START宏,获取可变参数列表的第一个参数的地址(ap是类型为va_list的指针,v是可变参数最左边的参数):
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
VA_ARG宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数(t参数描述了当前参数的类型):
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
VA_END宏,清空va_list可变参数列表:
#define va_end(ap) ( ap = (va_list)0 )
//其实va_start是将v后面的所有参数都放入ap这个va_list里了, 而va_arg不过获取下一个参数而已~
(详细去看百度百科)
其实本质上,利用的是:函数参数从右到左入栈的规则。测试代码:
void Test(int nCount, ...) { cout<<"--------利用函数参数从右至左入栈的规则获取所有参数-------------"<<endl; int* nTmp = &nCount; cout<<"Hi, you have input "<<*nTmp<<" arguments."<<endl; ++nTmp; cout<<"All other arguments are:"<<endl; for(int i = 0; i < nCount; ++i) { cout<<*nTmp<<" "; ++nTmp; } cout<<endl<<endl; } Test(4, 11, 12, 13, 14);
int vsnprintf(char *str, size_t size, const char *format, va_list ap); //Linux Edition: vsnprintf; Windows: _vsnprintf
测试代码:
/*test va_list 不定参数的使用方法*/ void Test__va_list(char* szFirstParam, ...) { /* cout<<"--------利用函数参数从右至左入栈的规则获取所有参数-------------"<<endl; int* nTmp = &nCount; cout<<"Hi, you have input "<<*nTmp<<" arguments."<<endl; ++nTmp; cout<<"All other arguments are:"<<endl; for(int i = 0; i < nCount; ++i) { cout<<*nTmp<<" "; ++nTmp; } cout<<endl<<endl; */ cout<<"---------利用封装的va_list获取所有参数------------"<<endl; va_list args; va_start(args, szFirstParam); char* chPara = NULL; while(1) { chPara = va_arg(args, char*); if(strcmp(chPara, "") == 0) break; cout<<chPara<<" "; } va_end(args); } void MyFormat(char* szDest, int nSizeDest, char* szFormat, ...) /*user is reponsible for the memory allocation and free of szDest and szFormat*/ { cout<<"----------测试将va_list和_vsnprintf结合起来----------"<<endl; va_list args; va_start(args, szFormat); _vsnprintf(szDest, nSizeDest, szFormat, args); va_end(args); } void Func21() { Test__va_list("Demo:", "This", "Is", "A", "Demo!", ""); cout<<endl; char szDest[50] = {0}; MyFormat(szDest, 50-1, "Test:%d%s", 99, "Ninety-Nine"); cout<<szDest<<endl; }
测试结果:
---------利用封装的va_list获取所有参数------------
This Is A Demo!
----------测试将va_list和_vsnprintf结合起来----------
Test:99Ninety-Nine

浙公网安备 33010602011771号