8

我们需要将格式 _TCHAR * 字符串和一些 char * 字符串传递给具有可变长度参数的函数:

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

所以可以这样调用:

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

显然,一个简单的解决方法是使用 _TCHAR 而不是 char,但不幸的是我们没有这种奢侈。

我们需要将它与 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 * - 但是如何?

4

4 回答 4

3

使用 %hs 或 %hS 代替 %s。这将强制在 Ansi 和 Unicode 版本的 printf() 样式函数中将参数解释为 char*,即:

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); 
}
于 2009-10-23T23:53:04.997 回答
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

你的问题并不完全清楚。你的功能是如何实现的,你是如何使用它的?

于 2009-10-23T13:16:09.310 回答
1

这是我的解决方案 - 我欢迎提出改进建议!

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
}
于 2009-10-24T10:18:50.157 回答
0

这是我以前用来将 TCHAR 转换为 char 的东西,希望它有所帮助,虽然我并不是真的在寻找优化,所以它不是最快的方法.. 但它有效!

    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);
于 2009-10-23T13:55:53.707 回答