繁体   English   中英

Function 带可变长度参数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM