2008-12-05 55 views

Trả lời

10

Phụ thuộc nếu nó là Unicode hay không nó xuất hiện. LPTSTR là char * nếu không phải là Unicode, hoặc w_char * nếu có.

Discussed better here (trả lời chấp nhận giá trị đọc)

7

Dưới đây là nhiều cách để thực hiện việc này. MFC hoặc ATL của CString, ATL macro, hoặc Win32 API.

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

Bạn có thể sử dụng các macro ATL để chuyển đổi:

USES_CONVERSION; 
pBuffer = T2A(szString); 

CString:

CStringA cstrText(szString); 

hoặc API Win32 WideCharToMultiByte nếu UNICODE được định nghĩa.

+1

Việc sử dụng nói trên của macro chuyển đổi ATL là lỗi thời (có lẽ đó là sử dụng hợp lệ cho VC6 và ATL3, nhưng kể từ khi VC7 thay đổi). Macro 'T2A' có' USES_CONVERSION' không được dùng nữa. Tốt hơn nên sử dụng ATL7 + [người trợ giúp chuyển đổi] (http://msdn.microsoft.com/en-us/library/87zae4a3 (v = vs.80) .aspx) như 'CT2A' (không có' 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

Nếu tôi sử dụng cách này tôi nhận được lỗi này C2664: 'strlen': không thể chuyển đổi tham số 1 từ 'LPTSTR' thành 'const char *' –

6

Nếu trình biên dịch Setting nhân vật của bạn được thiết lập để Unicode Character Set, sau đó LPTSTR sẽ được hiểu là wchar_t *. Trong trường hợp đó, cần phải chuyển đổi ký tự Unicode sang Multibyte.
(Trong Visual Studio, thiết lập tọa lạc tại Project Properties \ Configuration Properties \ chung \ Character Set)

Mẫu mã dưới đây sẽ đưa ra một ý tưởng:

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

Mặt khác, nếu bạn Cài đặt ký tự của trình biên dịch được đặt thành Multibyte, sau đó LPTSTR sẽ được hiểu là char *.

Trong trường hợp đó:

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

Xem thêm:

Một cuộc thảo luận về chuyển đổi wchar_t: How do you properly use WideCharToMultiByte
MSDN Điều: http://msdn.microsoft.com/en-us/library/dd374130(v=vs.85).aspx
trị định danh Mã Page: http://msdn.microsoft.com/en-us/library/dd317756(v=vs.85).aspx

-1

không có nghi ngờ nhiều người (ví dụ, chúng tôi unix dân gian) sẽ giật mình trong kinh dị ở mũ điên ter Microserf doublespeak - "nếu trình biên dịch của bạn ở chế độ Unicode, hãy sử dụng LPWSTR hoặc dán" T_ "trước nó, nhưng chỉ khi đó là chuỗi tĩnh, giống như" L "hoặc sử dụng T2A() nếu bằng cách sử dụng ATL, nhưng bây giờ đã lỗi thời, hoặc sử dụng VARIANT nhưng không phải nếu liên kết với COM/OLE "...).

"if (sizeof (TCHAR) == sizeof (char))" được liệt kê trên trang này là một nỗ lực hợp lý tại một giải pháp tốt đẹp, nhưng nó sẽ không biên dịch - hoặc nếu sự thật sẽ không biên dịch hoặc if-false sẽ không biên dịch, tùy thuộc vào cờ trình biên dịch của bạn (Aaargh!). Đối với giải pháp di động ghi và quên, bạn cần phải sử dụng macro UNICODE [quá chung chung tên].Tôi cung cấp khả năng thích ứng của mã trước:

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, vì vậy hãy nói rằng bạn PHẢI sử dụng Unicode. Và bạn sử dụng một số chức năng như LookupAccountSid, chúng được yêu cầu cho chương trình của bạn hoạt động - nhưng chúng trả về LPTSTR cho thông tin quan trọng bạn CẦN xử lý dưới dạng chuỗi (vì lý do gì - lập trình, những thứ như thế này xảy ra)

Bây giờ, nếu bạn đang sử dụng multibyte - đây không phải là vấn đề. Nhưng có một cách để giải quyết nó. Đây là phương pháp của tôi và được thừa nhận là cẩu thả. Nhưng dù sao bạn cũng có thể thấy nó hoạt động như thế nào.

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 

Mọi câu hỏi chỉ hỏi. Tôi nhận ra đây là một bài đăng cũ - nhưng tôi thích đăng bài cho những người trong cuộc thi tìm kiếm. (những người như tôi)

0

Tôi hy vọng điều này sẽ giúp ai đó, bởi vì tôi mất một thời gian để tìm ra cách để làm điều đó.

Trước hết, LPTSTR là loại con trỏ và về cơ bản tương đương với TCHAR* (giả sử rằng <tchar.h> được bao gồm). Lưu ý rằng kích thước của TCHAR thay đổi dựa trên loại mã hóa ký tự. tức là nếu mã unicode được xác định, TCHAR bằng wchar_t, nếu không thì là char.

Một cách tự nhiên, nếu bạn chuyển đổi một ký tự rộng thành char bình thường, bạn chỉ có thể giữ LSB và có thể mất một số dữ liệu. Điều này là bằng cách nào đó gây khó chịu cho tôi. vì vậy tôi đã viết đoạn mã sau. Ưu điểm chính của nó là thực hiện chuyển đổi mà không làm mất bất kỳ dữ liệu nào.

Nhân tiện, nếu bạn không hài lòng với việc mất dữ liệu, thì wcstombs sẽ thực hiện công việc.

#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

tôi đã thiếu một số ví dụ đơn giản như vậy ở đây nó là:

(đối với tôi char * là giống hệt nhau để char [])

LPCTSTR myLPCTSTR = getLPCTSTR(); 
TCHAR myT[500]; 
wcscpy(myT,myLPCTSTR); 
char myC[500]; 
sprintf(myC, "%S", myT); 
Các vấn đề liên quan