使用 C++ 可变长度参数时如何将 _TCHAR * 转换为 char *?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1613217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I convert from _TCHAR * to char * when using C++ variable-length args?
提问by Nick Bolton
We need to pass a format _TCHAR * string, and a number of char * strings into a function with variable-length args:
我们需要将格式 _TCHAR * 字符串和一些 char * 字符串传递到具有可变长度参数的函数中:
inline void FooBar(const _TCHAR *szFmt, const char *cArgs, ...) {
//...
}
So it can be called like so:
所以可以这样调用:
char *foo = "foo";
char *bar = "bar";
LogToFileA(_T("Test %s %s"), foo, bar);
Obviously a simple fix would be to use _TCHAR instead of char, but we don't have that luxury unfortunately.
显然,一个简单的解决方法是使用 _TCHAR 而不是 char,但不幸的是我们没有这种奢侈。
We need to use this with va_start, etc so we can format a string:
我们需要将它与 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);
Unfortunately we cannot use this because it give us this error:
不幸的是,我们不能使用它,因为它给了我们这个错误:
Unhandled exception at 0x6a0d7f4f (msvcr90d.dll) in foobar.exe:
0xC0000005: Access violation reading location 0x2d86fead.
I'm thinking we need to convert our char * to _TCHAR * - but how?
我想我们需要将我们的 char * 转换为 _TCHAR * - 但是如何?
采纳答案by Remy Lebeau
Use %hs or %hS instead of %s. That will force the parameters to be interpretted as char* in both Ansi and Unicode versions of printf()-style functions, ie:
使用 %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);
}
回答by Kirill V. Lyadvinsky
Usually it looks like the following:
通常它看起来像下面这样:
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
Your question is not completely clear. How your function is implemented and how do you use it?
你的问题不完全清楚。你的功能是如何实现的,你如何使用它?
回答by Nick Bolton
Here was my solution - I welcome suggestions for improvement!
这是我的解决方案 - 我欢迎改进建议!
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
}
回答by David Menard
this is something I have used before to convert a TCHAR to char, hope it helps, although I wasn't really looking for optimization, so it's not the fastest way.. but it worked!
这是我之前用来将 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);

