[英]Function with Variable length argument
我在 C 中使用可变长度参数对 function 有以下问题:
案例一(作品)
myPrintf("%d %s", 24, "Hi There");
案例2 (作品)
char tempbuf[9]="Hi There";`
myPrintf("%s %d", tempbuf, 24)
案例3 (无效)
myPrintf("%s %d", "Hi There", 24)
有谁知道为什么案例 3 不起作用。 我可以看到str = va_arg(ap, char *);
在这种情况下返回24
而不是实际字符串。
myPrintf 的代码:(虽然功能不完整)
void myPrintf(char *fmt, ...)
{
int i,j,val,len;
char *str;
int len2;
va_list ap;
char tempBuf[128];
len=strlen(fmt);
memset(tempBuf,0,MAX_MSZ_LEN);
va_start(ap,fmt);
for(i=0; i<len; i++)
{
switch(fmt[i])
{
case '%' :
i++;
if( fmt[i] == 's' )
{
str = va_arg(ap, char *);
strcat(tempBuf, str);
}
else
if( fmt[i]=='i' || fmt[i]=='d' )
{
val=va_arg(ap,int);
sprintf(str,"%d",val);
strcat(tempBuf, str);
}
default :
len2=strlen(tempBuf);
tempBuf[len2]=fmt[i];
}
}
va_end(ap);
}
}
在%d
的情况下:
sprintf(str,"%d",val);
str
指向什么? 如果之前有%s
,它指向 arguments 格式之一,否则它是未初始化的——在这两种情况下,它都指向一个无效的写入位置。 您需要另一个临时缓冲区来将值写入。 您很幸运,案例 1 和 2 有效。
看看这段代码:
if( fmt[i]=='i' || fmt[i]=='d' )
{
val=va_arg(ap,int);
sprintf(str,"%d",val);
strcat(tempBuf, str);
}
那里的 sprintf() 调用试图向str
写一些东西。 什么是str? 当您像myPrintf("%s %d", "Hi There", 24)
一样调用它时, str
将是 2. 参数,即字符串“Hi There”。 您不能更改 C 中的字符串文字,这可能会失败并可能导致崩溃。
当您像myPrintf("%s %d", tempbuf, 24)
一样调用它时, str
将是tmpbuf
,这是一个数组,您可以写入它,这样就可以了。 但是它只能容纳 9 个字节的空间,因此很容易溢出该缓冲区。
你应该只做类似的事情
char tmp[32];
sprintf(tmp,"%d",val);
strcat(tempBuf, tmp);
我将 go 出局......在案例 3 的格式字符串后加一个逗号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.