记起上次深信服的一道考题,叫我们实现一个与printf功能相似的函数,也就是可变参数个数的函数问题,当时压根就无从下手。刚在网上搜了一下,果然有所收获。多说无益,动手写了个程序实例,感兴趣的朋友可以看看:
#include
<
iostream
>
#include < conio.h >
#include < stdio.h >
#include < stdarg.h > // 定义av_list、av_start、av_arg等宏
/* ******************************************************************
此函数的作用:
实现一个参数个数可变的函数,此函数的功能与printf类似,
但在格式处理上,不如printf丰富
无异常,返回一个true,否则返回false
format字符串的合法情况如下:
1."%%zyk%%zyk%%",OUTPUT:%zyk%zyk%
2."%dzyk%fzyk%s",OUTPUT:(int)zyk(float)zyk(string)
3."zyk", OUTPUT:zyk
非法情况如下:
1."%zyk%" ERROR:不存在%z格式、%后面必须跟一个格式字符
****************************************************************** */
bool zykPrintf( const char * format,...)
{
// 定义一个可用于指向参数的指针(实为char *),
va_list argPtr;
// 把函数的第一个参数format的地址传给argPtr
va_start(argPtr,format);
const int size = strlen(format) + 1 ;
char * tmp = new char [size];
memset(tmp, 0 , size);
while ( * format != 0 )
{
int i;
for (i = 0 ; i < size && * format != ' % ' && * format != 0 ; i ++ )
{
tmp[i] =* format ++ ;
}
tmp[i] = 0 ; // 在有效的字符串末尾作0值防护
printf( " %s " ,tmp);
if ( * format == 0 )
return true ;
switch ( *++ format)
{
// 按指定类型读取下一个参数,并打印
case ' d ' : { printf( " %d " , va_arg(argPtr, int )); break ;}
case ' s ' : { printf( " %s " , va_arg(argPtr, char * )); break ; }
case ' c ' : { printf( " %c " , va_arg(argPtr, char )); break ;}
case ' f ' : { printf( " %f " , va_arg(argPtr, float )); break ;}
// 对%%的处理
case ' % ' : { printf( " %% " ); break ; }
// 格式错误
default : { printf( " Error Ocurr!Please Check the Format! " ); return false ;}
}
++ format;
}
delete[] tmp;
return true ;
}
int main( int argc, char * argv[])
{
zykPrintf( " %zyk " ); // error
zykPrintf( " zyk% " ); // error
zykPrintf( " %%zyk%%zyk%% " ); // OUTPUT: %zyk%zyk%
zykPrintf( "/n zyk is a pretty boy! His age is %d and %s " , 5 , " I love zyk^_^! " );
getch();
return 0 ;
}
#include < conio.h >
#include < stdio.h >
#include < stdarg.h > // 定义av_list、av_start、av_arg等宏
/* ******************************************************************
此函数的作用:
实现一个参数个数可变的函数,此函数的功能与printf类似,
但在格式处理上,不如printf丰富
无异常,返回一个true,否则返回false
format字符串的合法情况如下:
1."%%zyk%%zyk%%",OUTPUT:%zyk%zyk%
2."%dzyk%fzyk%s",OUTPUT:(int)zyk(float)zyk(string)
3."zyk", OUTPUT:zyk
非法情况如下:
1."%zyk%" ERROR:不存在%z格式、%后面必须跟一个格式字符
****************************************************************** */
bool zykPrintf( const char * format,...)
{
// 定义一个可用于指向参数的指针(实为char *),
va_list argPtr;
// 把函数的第一个参数format的地址传给argPtr
va_start(argPtr,format);
const int size = strlen(format) + 1 ;
char * tmp = new char [size];
memset(tmp, 0 , size);
while ( * format != 0 )
{
int i;
for (i = 0 ; i < size && * format != ' % ' && * format != 0 ; i ++ )
{
tmp[i] =* format ++ ;
}
tmp[i] = 0 ; // 在有效的字符串末尾作0值防护
printf( " %s " ,tmp);
if ( * format == 0 )
return true ;
switch ( *++ format)
{
// 按指定类型读取下一个参数,并打印
case ' d ' : { printf( " %d " , va_arg(argPtr, int )); break ;}
case ' s ' : { printf( " %s " , va_arg(argPtr, char * )); break ; }
case ' c ' : { printf( " %c " , va_arg(argPtr, char )); break ;}
case ' f ' : { printf( " %f " , va_arg(argPtr, float )); break ;}
// 对%%的处理
case ' % ' : { printf( " %% " ); break ; }
// 格式错误
default : { printf( " Error Ocurr!Please Check the Format! " ); return false ;}
}
++ format;
}
delete[] tmp;
return true ;
}
int main( int argc, char * argv[])
{
zykPrintf( " %zyk " ); // error
zykPrintf( " zyk% " ); // error
zykPrintf( " %%zyk%%zyk%% " ); // OUTPUT: %zyk%zyk%
zykPrintf( "/n zyk is a pretty boy! His age is %d and %s " , 5 , " I love zyk^_^! " );
getch();
return 0 ;
}
有更好的方法,请贴上来。