2008-12-05 22 views

risposta

10

Dipende se è Unicode o non appare. LPTSTR è char * se non Unicode, o w_char * se è così.

Discussed better here (risposta accettata la pena di leggere)

7

Qui ci sono molti modi per farlo. MFC o ATL CString, macro ATL o API Win32.

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

È possibile utilizzare le macro ATL per convertire:

USES_CONVERSION; 
pBuffer = T2A(szString); 

CString:

CStringA cstrText(szString); 

o l'API Win32 WideCharToMultiByte se UNICODE è definito.

+1

atti di utilizzazione della macro di conversione ATL è obsoleto (probabilmente quell'uso era valido per VC6 e ATL3, ma da quando le cose VC7 sono cambiate). La macro 'T2A' con' USES_CONVERSION' è deprecata. È preferibile utilizzare ATL7 + [helper di conversione] (http://msdn.microsoft.com/en-us/library/87zae4a3 (v = vs80) .aspx) come 'CT2A' (senza' USES_CONVERSION'): 'CT2A ansiBuffer (szString); ' –

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

Se uso in questo modo ottengo questo errore C2664: 'strlen': impossibile convertire il parametro 1 da 'LPTSTR' a 'const char *' –

6

Se l'impostazione di caratteri compilatore è impostato su Unicode Character Set, quindi LPTSTR sarà interpretato come wchar_t *. In questo caso è richiesta la conversione dei caratteri da Unicode a Multibyte.
(In Visual Studio, l'impostazione si trova a Character Set Proprietà progetto \ Proprietà di configurazione \ General \)

Il codice di esempio riportato di seguito dovrebbe dare un'idea:

#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; 
} 

D'altra parte, se il L'impostazione caratteri del compilatore è impostata su Multibyte, quindi LPTSTR verrà interpretato come char *.

In tal caso:

LPTSTR x = "test"; 
char* y; 
y = x; 

Vedi anche:

Un'altra discussione su conversione wchar_t: How do you properly use WideCharToMultiByte
articolo MSDN: http://msdn.microsoft.com/en-us/library/dd374130(v=vs.85).aspx
validi Codice Pagina Identifiers: http://msdn.microsoft.com/en-us/library/dd317756(v=vs.85).aspx

-1

senza dubbio molti (per esempio, noi unix folk) si ritraggono inorriditi al matto ter Microserf doublespeak - "se il compilatore è in modalità Unicode, usa LPWSTR o aggiungi un" T_ "davanti a esso, ma solo se è una stringa statica, che è la stessa di una" L ", o usa T2A() se usando ATL, ma questo è ormai obsoleto, o usare VARIANT ma non se si collega con COM/OLE "...).

"if (sizeof (TCHAR) == sizeof (char))" elencato in questa pagina è un tentativo logico di una soluzione piacevole, ma non verrà compilato - l'if-true non verrà compilato o if-false non verrà compilato, a seconda delle bandiere del compilatore (Aaargh!). Per una soluzione portatile write-and-forget è necessario ricorrere alla macro UNICODE [troppo generica].Offro questo adattamento del codice precedente:

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

OK, quindi diciamo che DEVI usare Unicode. E tu usi alcune funzioni come LookupAccountSid, che sono necessarie per il tuo programma per funzionare - ma restituiscono LPTSTR per informazioni importanti che DEVONO elaborare come una stringa (per qualsiasi ragione - è la programmazione, cose come queste)

Ora, se si stesse usando multibyte, questo non sarebbe un problema. Ma c'è un modo per risolverlo. Questo è il mio metodo ed è certamente sciatto. Tuttavia, dovresti essere in grado di vedere come funziona.

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 

Qualsiasi domanda chieda. Mi rendo conto che questo è un vecchio post - ma mi piace postare per le persone che sono venute in cerca. (persone come me)

0

Spero che questo aiuti qualcuno, perché mi ci è voluto un po 'per capire come farlo.

Prima di tutto, LPTSTR è di tipo puntatore ed è fondamentalmente equivalente a TCHAR* (supponendo che sia incluso <tchar.h>). Si noti che la dimensione di TCHAR varia in base al tipo di codifica dei caratteri. Ad esempio, se è definito unicode, TCHAR è uguale a wchar_t, altrimenti è char.

Naturalmente, se si converte un carattere ampio in un normale char, è possibile mantenere solo l'LSB e potrebbero perdere alcuni dati. Questo era in qualche modo irritante per me. così ho scritto il seguente codice. Il suo principale vantaggio è fare la conversione senza perdere alcun dato.

A proposito, se si sta bene con la perdita di dati, quindi wcstombs fa il lavoro.

#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

mi mancava qualche semplice esempio ecco che è:

(per me char * è identico a char [])

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