2011-05-24 112 views
2

我具有以下对在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这种情况下实际字符串intead。

代码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); 
} 

}

+2

什么的'myPrintf()'的代码? – 2011-05-24 15:57:17

+2

我们需要查看'myPrintf'的代码才能提供很多帮助 - 它看起来像一个合理的代码片段。 – 2011-05-24 15:57:46

+0

你有没有myprintf的任何代码? – 2011-05-24 15:57:51

回答

3

在这种情况下为%d

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

WH在str指向?如果之前有%s,它指向格式参数之一,否则它是未初始化的 - 在这两种情况下,它指向写入的无效位置。您需要另一个临时缓冲区来写入值。你只是幸运的案件1和2的工作。

+0

@Punit:你可以发布你的更新代码吗? – casablanca 2011-05-24 16:20:44

+0

@Punit:当'%d'在'%s'之前,'str'未初始化时 - 你运行起来很幸运,它可能会崩溃。在'%s'之后使用'%d',当您使用“Hi There”字符数组时,您可以在技术上修改它,因为您为它分配了空间。当你直接传递“Hi There”时,它是一个'const'字符串,所以你不能写信给它。 – casablanca 2011-05-24 16:56:21

0

我会去上肢体......加上一个逗号格式字符串后情况3 。

+0

你可以在这里放置修改过的行吗?哪个逗号? – Punit 2011-05-24 16:09:50

+0

我猜你的真实代码缺少逗号:myPrintf(“%s%d”“Hi There”,24);并且字符串被连接起来。 – 2011-05-24 16:11:11

1

这个代码看看:

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);