2008-12-05 150 views

回答

10

取決於它是否是Unicode它出現。如果不是Unicode,則LPTSTR是char *,如果是,則爲w_char *。

Discussed better here(接受的答案值得一讀)

7

這裏有很多方法來做到這一點。 MFC或ATL的CString,ATL宏或Win32 API。

LPTSTR szString = _T("Testing"); 
char* pBuffer; 

您可以使用ATL宏轉換:

USES_CONVERSION; 
pBuffer = T2A(szString); 

的CString:

CStringA cstrText(szString); 

或在Win32 API WideCharToMultiByte如果UNICODE定義。

+1

上述使用ATL轉換宏的是過時的(可能這個用法對VC6和ATL3有效,但是因爲VC7的東西改變了)。棄用「USES_CONVERSION」的`T2A`宏。使用ATL7 + [轉換助手](http://msdn.microsoft.com/en-us/library/87zae4a3(v = vs.80).aspx)比`CT2A`(不含`USES_CONVERSION`)更好:`CT2A 'ansiBuffer(szString);` – 2012-05-21 17:28:20

3
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); 
} 
+0

如果我使用這種方式,我得到這個錯誤C2664:'strlen':不能將參數1從'LPTSTR'轉換爲'const char *' – 2012-05-21 09:59:11

6

如果你的編譯人物設定設爲Unicode字符集,然後LPTSTR將被解釋爲wchar_t的*。在這種情況下,Unicode到Multibyte字符轉換是必需的。
(在Visual Studio中,設置位於項目屬性\配置屬性\一般\字符集)

下面的示例代碼應該給一個想法:

#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的轉換另一個討論:How do you properly use 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

-1

無疑許多人(例如,我們unix民間)會對這個瘋帽子感到恐懼ter Microserf doublespeak - 「如果您的編譯器處於Unicode模式,請使用LPWSTR或在其前面添加」T_「,但僅限於它是靜態字符串,與」L「相同或使用T2A()if使用ATL,但現在已經過時,或者使用VARIANT,但如果與COM/OLE鏈接「...」)。

此頁面上列出的「if(sizeof(TCHAR)== sizeof(char))」是一個很好的解決方案的邏輯嘗試,但它不會編譯 - if-true不會編譯或if-false不會'編譯,這取決於你的編譯器標誌(Aaargh!)。 對於一個寫下來忘記的便攜式解決方案,您需要使用[過於通用的命名] 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; 
} 
0

好了,讓我們說,你必須使用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 

有任何問題只是問。我意識到這是一箇舊帖子 - 但我喜歡在後期尋找的人羣中發佈帖子。 (像我這樣的人)

0

我希望這可以幫助別人,因爲我花了一段時間才弄清楚如何去做。

首先,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 
} 
0

我錯過了一些簡單的例子,所以在這裏,它是:

(對我來說char *之等同爲char [])

LPCTSTR myLPCTSTR = getLPCTSTR(); 
TCHAR myT[500]; 
wcscpy(myT,myLPCTSTR); 
char myC[500]; 
sprintf(myC, "%S", myT);