2009-10-23 13 views
8

हमें एक प्रारूप _TCHAR * स्ट्रिंग, और चर के चार स्ट्रिंग्स को चर-लंबाई वाले तर्कों के साथ एक फ़ंक्शन में पास करने की आवश्यकता है:C++ चर-लंबाई तर्क का उपयोग करते समय मैं _TCHAR * से char * में कैसे परिवर्तित करूं?

inline void FooBar(const _TCHAR *szFmt, const char *cArgs, ...) { 
    //... 
} 

तो इसे ऐसा कहा जा सकता है:

char *foo = "foo"; 
char *bar = "bar"; 
LogToFileA(_T("Test %s %s"), foo, bar); 

जाहिर है एक साधारण फिक्स का उपयोग char के बजाय _TCHAR का उपयोग करना होगा, लेकिन हमारे पास दुर्भाग्य से उस लक्जरी नहीं है।

हमें va_start, आदि के साथ इसका उपयोग करने की आवश्यकता है ताकि हम एक स्ट्रिंग को प्रारूपित कर सकें:

va_list args; 
_TCHAR szBuf[BUFFER_MED_SIZE]; 

va_start(args, cArgs); 
_vstprintf_s(szBuf, BUFFER_MED_SIZE, szFmt, args); 
va_end(args); 

दुर्भाग्यवश हम इसका उपयोग नहीं कर सकते क्योंकि यह हमें यह त्रुटि देता है:

Unhandled exception at 0x6a0d7f4f (msvcr90d.dll) in foobar.exe: 
0xC0000005: Access violation reading location 0x2d86fead. 

मैं सोच रहा हूं हमें अपने char * को _TCHAR * में परिवर्तित करने की आवश्यकता है - लेकिन कैसे?

+0

यदि आप एक wchar * एक चार * के बजाय का उपयोग कर के लक्जरी है, मैं यह है कि आप समस्या –

+0

हम्म, दुर्भाग्य से नहीं तय होगा लगता है - वर्तमान प्रणाली चार * और _TCHAR * –

+0

की एक mish मैश है यह बहुत बुरा है ... दक्षता एक मुद्दा है? यदि नहीं, तो मेरे उत्तर पर एक नज़र डालें, यह मेरे लिए काम करता है –

उत्तर

3

% s के बजाय% hs या% hS का उपयोग करें। मेरी समाधान

inline void LogToFile(const _TCHAR *szFmt, ...) 
{ 
    va_list args; 
    TCHAR szBuf[BUFFER_MED_SIZE]; 

    va_start(args, szFmt); 
    _vstprintf_s(szBuf, BUFFER_MED_SIZE, szFmt, args); 
    va_end(args); 
} 

{ 
    char *foo = "foo"; 
    char *bar = "bar"; 
    LogToFile(_T("Test %hs %hs"), foo, bar); 
} 
+0

बहुत अच्छा जवाब। –

2

आमतौर पर यह ऐसा दिखाई देता है:

char *foo = "foo"; 
char *bar = "bar"; 
#ifdef UNICODE 
LogToFileW(L"Test %S %S", foo, bar); // big S 
#else 
LogToFileA("Test %s %s", foo, bar); 
#endif 

आपका प्रश्न पूरी तरह से स्पष्ट नहीं है। आपका फ़ंक्शन कैसे कार्यान्वित किया जाता है और आप इसका उपयोग कैसे करते हैं?

+1

% s और% s के बजाय% hs या% hS का उपयोग करें। इससे अंसी और यूनिकोड दोनों में char * को मजबूर कर दिया जाएगा। फिर आप यूनिकोड के लिए चेक हटा सकते हैं। –

0

यह ऐसा कुछ है जिसे मैंने टीसीएचएआर को चार में बदलने के लिए पहले उपयोग किया है, उम्मीद है कि यह मदद करता है, हालांकि मैं वास्तव में अनुकूलन की तलाश नहीं कर रहा था, इसलिए यह सबसे तेज़ तरीका नहीं है .. लेकिन यह काम करता है!

TCHAR tmp[255]; 
::GetWindowText(hwnd, tmp, 255); 
std::wstring s = tmp; 

//convert from wchar to char 
const wchar_t* wstr = s.c_str(); 
size_t wlen = wcslen(wstr) + 1; 
char newchar[100]; 
size_t convertedChars = 0; 
wcstombs_s(&convertedChars, newchar, wlen, wstr, _TRUNCATE); 
1

यहाँ था - मैं सुधार के लिए सुझावों का स्वागत: यानी शैली काम करता है, - वह मापदंडों के लिए बाध्य करेगा printf के दोनों Ansi और यूनिकोड संस्करण() में चार * के रूप में interpretted जा करने के लिए!

inline void FooBar(const _TCHAR *szFmt, const char *cArgs, ...) { 

    va_list args; 
    _TCHAR szBuf[BUFFER_MED_SIZE]; 

    // Count the number of arguments in the format string. 
    const _TCHAR *at = _tcschr(szFmt, '%'); 
    int argCount = 0; 
    while(at) { 
     argCount++; 
     at = _tcschr(at + 1, '%'); 
    } 

    CA2W *ca2wArr[100]; 
    LPWSTR szArgs[100]; 
    va_start(args, cArgs); 
    for (int i = 1; i < argCount + 1; i++) { 
     CA2W *ca2w = new CA2W(cArgs); 
     szArgs[i] = ca2w->m_psz; 
     ca2wArr[i] = ca2w; 
     cArgs = va_arg(args, const char *); 
    } 
    va_end(args); 

    // Use the new array we just created (skips over first element). 
    va_start(args, szArgs[0]); 
    _vstprintf_s(szBuf, BUFFER_MED_SIZE, szFmt, args); 
    va_end(args); 

    // Free up memory used by CA2W objects. 
    for (int i = 1; i < argCount + 1; i++) { 
     delete ca2wArr[i]; 
    } 

    // ... snip ... - code that uses szBuf 
} 
+0

तर्कों की गिनती करने के लिए आपका लूप "%%" अक्षर की अनुमति नहीं देता है, और va_arg() का उपयोग 32-बिट से बड़े पैरामीटर के लिए अनुमति नहीं देता है। इसके अलावा, चूंकि _vstprintf_s() पहले से ही अंसी और यूनिकोड दोनों का समर्थन करता है, इसलिए इस तरह के विस्तृत कोड के साथ शुरुआत करने की आवश्यकता नहीं है। क्या मैंने आपके द्वारा पहले दिए गए कोड में कोई समस्या थी? –

+0

आह आप काउंटर के बारे में सही हैं। आपके कोड के बारे में, हाँ, यह ठीक काम करेगा, मुझे लगता है, और हम इसे नए कोड के लिए उपयोग करने जा रहे हैं जिसे हम कार्यान्वित करते हैं, हालांकि मौजूदा (त्रुटिपूर्ण) उपयोगों के लिए हमें अपने उत्तर में अस्थायी हैक फ़ंक्शन का उपयोग करना होगा। –

संबंधित मुद्दे