有人会碰巧知道如何将类型转换LPTSTR
为char *
C++ 吗?
8 回答
取决于它是否显示为 Unicode。如果不是 Unicode,LPTSTR 是 char*,如果是,则为 w_char*。
在这里讨论得更好(接受的答案值得阅读)
这里有很多方法可以做到这一点。MFC 或 ATL 的 CString、ATL 宏或 Win32 API。
LPTSTR szString = _T("Testing");
char* pBuffer;
您可以使用 ATL 宏来转换:
USES_CONVERSION;
pBuffer = T2A(szString);
字符串:
CStringA cstrText(szString);
或 Win32 API (WideCharToMultiByte
如果UNICODE
已定义)。
如果您的编译器 Character Setting 设置为Unicode Character Set,则LPTSTR将被解释为wchar_t*。在这种情况下,需要 Unicode 到多字节字符的转换。
(在 Visual Studio 中,设置位于 Project Properties\Configuration Properties\General\Character Set)
下面的示例代码应该给出一个想法:
#include <windows.h>
/* string consisting of several Asian characters */
LPTSTR wcsString = L"\u9580\u961c\u9640\u963f\u963b\u9644";
//LPTSTR wcsString = L"OnlyAsciiCharacters";
char* encode(const wchar_t* wstr, unsigned int codePage)
{
int sizeNeeded = WideCharToMultiByte(codePage, 0, wstr, -1, NULL, 0, NULL, NULL);
char* encodedStr = new char[sizeNeeded];
WideCharToMultiByte(codePage, 0, wstr, -1, encodedStr, sizeNeeded, NULL, NULL);
return encodedStr;
}
wchar_t* decode(const char* encodedStr, unsigned int codePage)
{
int sizeNeeded = MultiByteToWideChar(codePage, 0, encodedStr, -1, NULL, 0);
wchar_t* decodedStr = new wchar_t[sizeNeeded ];
MultiByteToWideChar(codePage, 0, encodedStr, -1, decodedStr, sizeNeeded );
return decodedStr;
}
int main(int argc, char* argv[])
{
char* str = encode(wcsString, CP_UTF8); //UTF-8 encoding
wchar_t* wstr = decode(str, CP_UTF8);
//If the wcsString is UTF-8 encodable, then this comparison will result to true.
//(As i remember some of the Chinese dialects cannot be UTF-8 encoded
bool ok = memcmp(wstr, wcsString, sizeof(wchar_t) * wcslen(wcsString)) == 0;
delete str;
delete wstr;
str = encode(wcsString, 20127); //US-ASCII (7-bit) encoding
wstr = decode(str, 20127);
//If there were non-ascii characters existing on wcsString,
//we cannot return back, since some of the data is lost
ok = memcmp(wstr, wcsString, sizeof(wchar_t) * wcslen(wcsString)) == 0;
delete str;
delete wstr;
}
另一方面,如果您的编译器字符设置设置为多字节,则LPTSTR将被解释为char*。
在这种情况下:
LPTSTR x = "test";
char* y;
y = x;
另见:
关于 wchar_t 转换的另一个讨论:如何正确使用 WideCharToMultiByte
MSDN 文章: http: //msdn.microsoft.com/en-us/library/dd374130
(v=vs.85).aspx
有效代码页标识符:http:// msdn.microsoft.com/en-us/library/dd317756(v=vs.85).aspx
char * pCopy = NULL;
if (sizeof(TCHAR) == sizeof(char))
{
size_t size = strlen(pOriginal);
pCopy = new char[size + 1];
strcpy(pCopy, pOriginal);
}
else
{
size_t size = wcstombs(NULL, pOriginal, 0);
pCopy = new char[size + 1];
wcstombs(pCopy, pOriginal, size + 1);
}
好的,假设您必须使用 Unicode。你使用了一些像 LookupAccountSid 这样的函数,这些函数是你的程序运行所必需的——但它们会返回 LPTSTR 以获得你需要作为字符串处理的重要信息(无论出于何种原因——它正在编程,会发生这样的事情)
现在,如果您使用多字节 - 这将不是问题。但是有一种方法可以解决它。这是我的方法,诚然是草率的。但尽管如此,您应该能够看到它是如何工作的。
const std::wstring &wstring = AcctName; // AcctName being my LPTSTR string
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstring[0], (int)wstring.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, & wstring[0], (int)wstring[0], &strTo[0], size_needed, NULL, NULL);
char* charUserName = new char[strTo.size() + 1];
// Set charUserName via copying
std::copy(strTo.begin(), strTo.end(), charUserName);
charUserName[strTo.size()] = '\0';
SetUPI(charUserName); // charUserName being my converted char * -
// You don't need this last part - but this is an example of passing to method
// that takes a string
任何问题都可以问。我意识到这是一个旧帖子 - 但我喜欢为未来的人发帖。(像我这样的人)
我希望这对某人有所帮助,因为我花了一段时间才弄清楚如何去做。
首先,LPTSTR
是指针类型,它基本上等价于TCHAR*
(假设<tchar.h>
包括在内)。请注意,大小TCHAR
因字符编码类型而异。即,如果定义了 unicode,TCHAR
则等于wchar_t
,否则为char
。
自然,如果将宽字符转换为普通字符char
,则只能保留 LSB,可能会丢失一些数据。这对我来说有点恼火。所以我写了下面的代码。它的主要优点是在不丢失任何数据的情况下进行转换。
顺便说一句,如果您对数据丢失没问题,那么wcstombs
就可以完成这项工作。
#include <cstring>
#include <algorithm>
#include <tchar.h>
void lptstr2str(LPTSTR tch, char* &pch) // or (TCHAR* tch, char* &pch)
{
#ifndef UNICODE
std::memcpy(pch, tch, strlen(tch) + 1);
#else
size_t n =
sizeof(TCHAR) / sizeof(char)* wcsnlen(tch, std::string::npos);
pch = new char[n + 1];
std::memcpy(pch, tch, n + 1);
int len = n - std::count(pch, pch + n, NULL);
std::remove(pch, pch + n, NULL);
pch[len] = NULL;
#endif
}
我错过了一些简单的例子,所以这里是:
(对我来说 char* 与 char[] 相同)
LPCTSTR myLPCTSTR = getLPCTSTR();
TCHAR myT[500];
wcscpy(myT,myLPCTSTR);
char myC[500];
sprintf(myC, "%S", myT);
毫无疑问,许多人(例如,我们的 unix 人)会害怕发疯的 Microserf 双语 - “如果你的编译器处于 Unicode 模式,请使用 LPWSTR 或在它前面加上一个“T_”,但前提是它是静态的字符串,与“L”相同,或者如果使用 ATL,则使用 T2A(),但现在已经过时,或者使用 VARIANT,但如果与 COM/OLE 链接则不使用"...)。
此页面上列出的“if (sizeof(TCHAR) == sizeof(char))”是一个很好的解决方案的合乎逻辑的尝试,但它不会编译 - if-true 不会编译或 if-false 不会' 编译,取决于你的编译器标志(Aaargh!)。对于写后忘记的便携式解决方案,您需要求助于 [too-generic named] UNICODE 宏。我提供了对先前代码的这种改编:
string mfc_to_zstring (CString &sref)
{
char nojoy[65536];
char *ptr, *psin = NULL;
string sot;
LPCTSTR p = sref;
#if UNICODE
if (sizeof(TCHAR) != sizeof(char))
{
size_t n = wcstombs(NULL, p, 0);
if (n > 65530)
{
psin = new char[n + 1];
wcstombs(psin, p, n + 1);
ptr = psin;
}
else
{
wcstombs(nojoy, p, n + 1);
ptr = nojoy;
}
sot = ptr;
if (psin != NULL)
delete psin;
}
else
{ std::cerr << "Aaargh! Microsoft horror.\n"; exit(1); }
#else
if (sizeof(TCHAR) == sizeof(char))
{
const char *ptr = p;
sot = ptr;
}
else
{ std::cerr << "Aaargh! You should never see this line\n"; exit(1); }
#endif
return sot;
}