2016-01-25 30 views
1
風格功能

(至少在這個Q的緣故)唱的Borland C++ Builder的2009年定製的sprintf(...),只有變量輸入

在自定義類,它是相當於一個String類我有一個功能,像這樣:

(編輯的位用於此Q)

MyString &MyString::Sprintf(const wchar_t *Text, ...) 
{ 
    wchar_t ResultStr[1000] ; 
    va_list List ; 
    va_start (List, Text) ; 
    int cnt = vswprintf (ResultStr, Text, List) ; 
    #ifdef _DEBUG 
    if (cnt >= (int)sizeof(ResultStr)) {throw (sizeof(ResultStr)) ;} 
    #endif 
    va_end (List) ; 
    my_internally_handled_string.assign(ResultStr) ; 
    return *this; 
} 

我然而想調整此函數(或再拍一張),其只在該變量作爲輸入,並且使用類'作爲的輸入Text的內部管理的字符串功能。

事情是這樣的:

MyString &MyString::Sprintf(...) 
{ 
    const wchar_t *Text = my_internally_handled_string.c_str() ; 
    // ... Rest see above 

然而,這並不工作。 vswprintf引發異常。 (在my_internally_handled_string中使用完美的OK文本進行測試)

我想知道它是否完全可能和/或我需要做什麼才能使它按照我設想的方式工作?的va_start()

+0

'{throw(sizeof(ResultStr))'??你也應該比較字符的數量,而不是'sizeof'。 –

+0

這將有助於用您的實際代碼替換「請參閱上文」。我無法猜測你用什麼替換了'va_start(List,Text)'。 –

+0

請確保您不嘗試覆蓋您的格式字符串存儲在同一內存中,而您仍然在閱讀格式字符串...對於您需要將內部字符串複製到單獨的緩衝區開始覆蓋它。 –

回答

2

的變量(或variadic)參數(stdarg.h/cstdarg)是從C繼承macros第二個參數是最後的非可變參數(在你的情況const wchar_t *Text)。這是計算以下變量參數起始地址的參考點。如果在...之前沒有最後一個參數,那麼它沒有找到可變參數的參考點。所以你需要東西給它,如一個虛擬參數。

您可以保留現有的函數簽名

MyString &MyString::Sprintf(const wchar_t *Text, ...) 

,只是沒有使用其他的參數Text比打電話va_start(List, Text)。請記住,你可以通過任何你想vswprintf(),如

vswprintf(ResultStr, my_internally_handled_string.c_str(), List); 

另外,不要使用相同名稱的局部變量陰影參數Text,尤其是在調用va_start()之前,因爲它需要參數爲一個起點。

另一件值得一提的C++變量參數是don't use a reference variable作爲...之前的最後一個參數。

+0

謝謝澄清。我其實已經嘗試過類似的東西(成功),但我的目標是擺脫除了實際變量以外的其他任何東西,所以只能使用:(...)'。我現在看到那是不可能的。 – Peter