请问如何将va_list变参透明的传递到下一个函数?

vcbear 2003-10-23 10:07:00

int vp2(char *pFormat ,...)
{
va_list args;
va_start (args, pFormat);
.....
va_end (args);

}
int vp1(char *pFormat ,...)
{
vp2(????); //}



见"????"处,这是两个对变参进行格式化的函数,但是两个函数里针对变参各有一些不同的处理,调用层次是vp1调用vp2,如何将传进vp1的格式和可变参数传递到vp2里呢。我试过这样不成功。一时没查到资料该怎么办,后来就干脆先用一个buffer格式化了数据再传了。请指点,谢谢。

代码:
int vp1(char *pFormat ,...)
{
va_list args;
va_start (args, pFormat);
vp2(args);
va_end (args);

}

我有想过用va_arg,可是好象不是很方便。有没有高人给出一个有效的解决方法?谢谢
...全文
836 17 打赏 收藏 举报
写回复
17 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
vcbear 2003-10-23
哦,来个权威告诉我此路绝对不通也是值得感激的,真的不通吗...
  • 打赏
  • 举报
回复
fierygnu 2003-10-23
不行。vp2需要两个原型满足不同需要,就象printf于vprintf。
  • 打赏
  • 举报
回复
vcbear 2003-10-23
如果是
vp2(char *pFormat,va_list args)
..

vp1(char *pFormat,...)
{
va_list args;
va_start(
vp2(pFormat,args)
va_end
}
是可行的。
不过我在想怎么做成vp2也可以这样定义vp2(char *pFormat,...),呵呵,好象就差一点,脑子一时转不过来了。
  • 打赏
  • 举报
回复
fierygnu 2003-10-23
va_list是可以的。是否是混和使用了stdarg和varargs两套接口导致不成功?
  • 打赏
  • 举报
回复
vcbear 2003-10-23
不算解决办法。因为我主贴已经提到类似的办法,我对此其实很不满意。
因为我希望能把va_list传过去,而不是一个格式化过的字符串。
我试过传va_list变量作为参数,可能是由于不同函数的调用堆栈不同吧,此路好象不通
  • 打赏
  • 举报
回复
scatzr 2003-10-23
sorry,maybe they would be written like the following:

void Out(char* format,...)
{

char buffer[256];
va_list vl;

va_start(vl,format);
vsprintf(buffer,format,vl);
va_end(vl);

printf(buffer);
}
void Out1(char* format,...)
{

char buffer[256];
va_list vl;

va_start(vl,format);
vsprintf(buffer,format,vl);
va_end(vl);

Out(buffer);
}

接分了:)
  • 打赏
  • 举报
回复
scatzr 2003-10-23
void Out(char* format,...)
{

char buffer[256];
va_list vl;

va_start(vl,format);
vsprintf(buffer,format,vl);
va_end(vl);

Trace(buffer,color);
}
void Out1(char* format,...)
{

char buffer[256];
va_list vl;

va_start(vl,format);
vsprintf(buffer,format,vl);
va_end(vl);

Out(buffer,color);
}

这算是种办法吗?:)
接分了:)
  • 打赏
  • 举报
回复
fierygnu 2003-10-23
另外vp2要这样:
int vp2(char *pFormat , va_list args)
{
...
}
  • 打赏
  • 举报
回复
fierygnu 2003-10-23
楼主的方法是唯一的方法。
  • 打赏
  • 举报
回复
fifo333 2003-10-23
关注中
  • 打赏
  • 举报
回复
sevencat 2003-10-23
CString的format不知道是怎么样实现的,上次想看的,后来又懒了。
  • 打赏
  • 举报
回复
Caoyu015 2003-10-23
//上楼的意思可能是这样吧?
void p(int paranum, ...)
{
char *ss[ 3 ];
va_list vaglist;
va_start( vaglist, paranum );
for( int ix = 0; ix < paranum; ix++ )
ss[ ix ] = va_arg( vaglist, char * );

p1( paranum,ss[ 0 ], ss[ 1 ], ss[ 2 ] );
}

不知道我有没有理解正确, 如果只是要作到va_list的参数透明的传递,能不能这样。

构造一个如下类型。

typedef enum{ VarInt, VarFloat, ......)TypeInfo;

typedef struct cnode{
TypeInfo tInfo; //指示类型
union {
int paramInt;
float paramFlaot;
......................
.......................
}
struct cnode *next;
}TypeNode;

typedef TypeNode *TypeList;

然后在V1函数中分析,后填充该链表当参数结束则为NULL结束该链表。这样就传递
一个 TypeList的参数就行了。


  • 打赏
  • 举报
回复
vcbear 2003-10-23
void p(int paranum, ...)
{
p1(paranum, ...);
}
编译不过(linux,gcc) :(
arg1.c: In function `p':
arg1.c:24: parse error before `...'
  • 打赏
  • 举报
回复
arfi 2003-10-23
下面的程序在WIN98系统下的TURBOC2编译环境下运行正常。(va_list在不同的系统上实现也不同)
当函数每调用含有...的参数一次,其值会发生改变(这一点是凭打印...的值做出的猜测)。
#include <stdio.h>
#include <stdarg.h>

void p1(int paranum, ...)
{
va_list ap; //在当前环境下它的类型就是void *
char *p;
int i;
int *varp;

va_start(ap, fmt);
varp = (int *)ap;
ap = (va_list)(*varp); //这纯粹是经过实验后的猜测。因为再次调用...时期值发生了变化,现在是取其上一层调用时的值。
for(i=0; i<paranum; i++)
{
p = va_arg(ap, char *);
printf("%s", p);
}
va_end(ap);
}

void p(int paranum, ...)
{
p1(paranum, ...);
}

void main(void)
{
char *s1 = "hello ";
char *s2 = "world ";
char *s3 = "more\n";

clrscr();
p(3, s1, s2, s3);
}

如果这种猜测是正确的话,那么函数的调用次序就得固定了,也就是说你不能在main函数中直接调用p1,否则会出错。
  • 打赏
  • 举报
回复
vcbear 2003-10-23
由于va_list里有vp1的所有变参信息,
原来我以为将va_list里的参数再怎么组织一下,成为vp2(pFormat,...)能理解的变参列表,
vp2再用同样的方式(va_start,va_end)得到一个va_list。
希望有编程技巧能实现。看来是挺困难的。
  • 打赏
  • 举报
回复
双杯献酒 2003-10-23
变参的函数,编译器需要在调用的时候确定参数个数,
以确定参数栈的大小,
您所希望的那种方式,显然无法提供这个信息,因此
是行不通的。
  • 打赏
  • 举报
回复
vcbear 2003-10-23
fierygnu(va_list) 的发言是今天最有价值的提示。谢。
看了一下printf和vprintf,既然设计了两个这样的函数,应该有其道理。
如果再没别的办法,我就打算这样实现了。
有没有其他大虾能提出更巧妙的方法呢?

  • 打赏
  • 举报
回复
相关推荐
发帖
C语言
加入

6.6w+

社区成员

C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
申请成为版主
帖子事件
创建了帖子
2003-10-23 10:07
社区公告
暂无公告