2016-04-27 42 views
1

我一直在試圖傳遞變量參數傳遞給其他函數C,但它產生不一致的結果,在不同的運行環境,以及在同一環境中不同的運行:傳遞va_list的其它功能

int main() 
{ 
    int result = myprintf("Something \n %d", 9); 
    return result; 
} 

int myprintf(const char *format, ...){ 
    printf("Something \n %d", 9); 
    printf("\n"); 
    va_list args;   
    va_start(args, format);  
    int result = printf(format,args); 
    printf("\n"); 
    va_end(args); 
    return result; 
} 

而產生的結果是:

WWW.FIRMCODES.COM 
9 
WWW.FIRMCODES.COM 
438656664 

我找不到「438656664」的原因。

+1

你不能那樣做;你只能將'args'傳遞給以'va_args'爲參數的函數。它們的名字中有一個'v':'vprintf','vfprintf','vsnprintf'。 –

+0

如果我需要通過printf()函數創建一個包裝,那麼我該如何繼續?我在想,我可以創建一個函數,在對格式字符串進行某些操作後,我會調用printf()。但正如你所建議的,我應該稱之爲「V」功能家族,對吧? – Monk

+0

是的,將'va_list'轉換爲''v'系列函數是一種可行的方法。不過,你可能不應該操縱格式字符串,至少不是格式說明符本身。 (你可以得到很多編譯器來檢查格式字符串和參數是否同意; gcc/clang通過屬性來做到這一點,VC++通過SAL註釋來做到這一點。如果你篡改格式字符串,這樣的檢查將毫無意義。) –

回答

2

您無法將可變參數傳遞給可變參數函數。相反,您必須調用一個以va_list作爲參數的函數。標準庫提供printfscanf的變體,其需要va_list;他們的名字有前綴v

你的榜樣應該是這樣的:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdarg.h> 

int printfln(const char *format, ...) 
{ 
    int result; 
    va_list args; 

    va_start(args, format); 
    result = vprintf(format, args); 
    printf("\n"); 
    va_end(args); 

    return result; 
} 

int main() 
{ 
    int result = printfln("Something \n %d", 9); 

    printf("(%d)\n", result); 

    return 0; 
} 

有一些陷阱,例如,當你想調用兩個v...函數打印到屏幕和日誌文件:v...功能可能會耗盡va_list,所以如果你的代碼應該是可移植的,你必須通過一個新的代碼。

+0

真棒。它工作正常。 – Monk

+1

va_copy可用於在耗盡它之前獲得「新鮮的」,並且必須使用va_end來釋放副本。 –