具有可变长度自变量的函数

问题描述

| 我对C中具有可变长度参数的函数有以下疑问: 案例1(作品)
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,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);
ѭ8指向什么?如果之前有一个“ 9”,则它指向格式参数之一,否则它未初始化-在两种情况下,它都指向一个无效的写入位置。您需要另一个临时缓冲区将值写入其中。您很幸运案例1和案例2成功了。     ,看一下这段代码:
   if( fmt[i]==\'i\' || fmt[i]==\'d\' )
    {
      val=va_arg(ap,int);
      sprintf(str,val);
      strcat(tempBuf,str);
    }
那里的sprintf()调用试图将内容写入ѭ8something。什么是str? 当您将其命名为ѭ12call时,
str
将成为参数2.,字符串“ Hi There \”。您无法在C中更改字符串文字,这可能会失败并可能导致崩溃。 当您像
myPrintf(\"%s %d\",tempbuf,24)
这样称呼它时,
str
将是
tmpbuf
,这是一个数组,您可以对其进行写入,这样就可以了。尽管它只保留9个字节的空间,所以很容易溢出该缓冲区。 你应该做一些类似的事情
      char tmp[32];
      sprintf(tmp,tmp);
    ,我会弯腰...在情况3的格式字符串后面加上逗号。