2011-05-24 117 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);