كيف يمكنني تحويل من _TCHAR * إلى شار * عند استخدام C ++ وسائط متغيرة الطول؟

StackOverflow https://stackoverflow.com/questions/1613217

  •  06-07-2019
  •  | 
  •  

سؤال

ونحن بحاجة لتمرير * سلسلة تنسيق _TCHAR، وعدد من شار * السلاسل في وظيفة مع وسائط متغيرة الطول:

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

وهكذا يمكن أن يسمى مثل ذلك:

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

من الواضح أن إصلاح بسيط يتمثل في استخدام _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.

وأنا أفكر أننا بحاجة لتحويل لدينا شار * ل_TCHAR * - ولكن كيف

هل كانت مفيدة؟

المحلول

استخدم٪ HS أو٪ HS بدلا من٪ الصورة. والتي تجبر المعلمات على أن interpretted كما شار * في كل العنسي ويونيكود إصدارات printf () - وظائف أسلوب، أي:

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

نصائح أخرى

وعادة ما يشبه ما يلي:

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

وسؤالك غير واضح تماما. كيف يتم تنفيذ الدالة وكيف استخدامه؟

وهنا كان لي حل - وأرحب اقتراحات لتحسين

!
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
}

وهذا شيء ولقد استخدمت من قبل لتحويل TCHAR إلى شار، ونأمل أن يساعد، على الرغم من أنني لم أكن حقا تبحث عن الأمثل، حتى انها ليست اسرع وسيلة .. لكنه يعمل!

    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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top