【问题标题】:Function with Variable length argument具有可变长度参数的函数
【发布时间】:2011-05-25 00:19:28
【问题描述】:

我对 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,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);
}

}

【问题讨论】:

  • myPrintf() 的代码是什么?
  • 我们需要查看myPrintf 的代码才能提供很多帮助 - 到目前为止,它看起来像是一个合理的代码片段。
  • 你有myprintf的代码吗?
  • myPrintfmyprintf 之间有什么区别?
  • 你确定在case 3格式字符串后面有逗号吗?

标签: c


【解决方案1】:

%d为例:

sprintf(str,"%d",val);

str 指向什么?如果之前有一个%s,它指向一个格式参数,否则它是未初始化的——在这两种情况下,它都指向一个无效的写入位置。您需要另一个临时缓冲区来将值写入。你很幸运,案例 1 和 2 成功了。

【讨论】:

  • @Punit:当%d%s 之前时,str 未初始化——你很幸运它成功了,它很可能会崩溃。在%s 之后使用%d,当您为“Hi There”使用字符数组时,您可以在技术上对其进行修改,因为您为它分配了空间。当你直接传递“Hi There”时,它是一个const 字符串,所以你不能写它。
【解决方案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);

【讨论】:

    【解决方案3】:

    我会冒险出去......在案例 3 的格式字符串后面加一个逗号。

    【讨论】:

    • 我猜你的真实代码缺少逗号:myPrintf("%s %d" "Hi There", 24);并且字符串正在连接。
    猜你喜欢
    • 2011-11-27
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    相关资源
    最近更新 更多