c ++ 가변 길이 Args를 사용할 때 _tchar *에서 char *로 어떻게 변환합니까?
문제
우리는 _tchar * 문자열 형식을 전달하고 여러 char * 문자열을 가변 길이의 args를 가진 함수로 전달해야합니다.
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 *로 변환해야한다고 생각하지만 어떻게?
해결책
%s 대신 %HS 또는 %HS를 사용하십시오. 이는 ANSI 및 유니 코드 버전의 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);
}
다른 팁
일반적으로 다음과 같습니다.
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
}
이것은 내가 TCHA를 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);
제휴하지 않습니다 StackOverflow