Có gì chênh lệch giữa LPCSTR, LPCTSTRvà LPTSTR?
Tại sao chúng ta cần làm điều này để chuyển đổi một chuỗi thành một biến LV/ _ITEMcấu trúc pszText:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Có gì chênh lệch giữa LPCSTR, LPCTSTRvà LPTSTR?
Tại sao chúng ta cần làm điều này để chuyển đổi một chuỗi thành một biến LV/ _ITEMcấu trúc pszText:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Câu trả lời:
Để trả lời phần đầu tiên của câu hỏi của bạn:
LPCSTRlà một con trỏ đến một chuỗi const (LP có nghĩa là Con trỏ dài )
LPCTSTRlà một con trỏ đến một const TCHARchuỗi, ( TCHARlà một ký tự rộng hoặc ký tự tùy thuộc vào việc UNICODE có được xác định trong dự án của bạn hay không)
LPTSTRlà một con trỏ đến một (không const) TCHARchuỗi
Trong thực tế khi nói về những điều này trong quá khứ, chúng ta đã bỏ qua cụm từ "con trỏ tới một" cho đơn giản, nhưng như đã đề cập bởi sự nhẹ nhàng-chủng tộc-trong quỹ đạo, chúng đều là con trỏ.
Đây là một bài viết về codeproject tuyệt vời mô tả các chuỗi C ++ (xem 2/3 đường xuống để biết biểu đồ so sánh các loại khác nhau)
extern "C". Ngoài điều đó, vâng, nó chắc chắn cần phải có bit "con trỏ" hoặc mô tả cụ thể dưới dạng chuỗi C.
Nhanh chóng và hèn hạ:
LP== L ong P ointer. Chỉ nghĩ con trỏ hoặc ký tự *
C= C onst, trong trường hợp này, tôi nghĩ rằng họ có nghĩa là chuỗi ký tự là một const, không phải là con trỏ là const.
STRlà chuỗi
những Tlà dành cho một nhân vật rộng hoặc char (TCHAR) tùy thuộc vào tùy chọn biên dịch.
char: Ký tự 8 bit - kiểu dữ liệu C / C ++ cơ bảnCHAR: bí danh của char- Kiểu dữ liệu WindowsLPSTR: chuỗi được kết thúc bằng null của CHAR ( L ong P ointer)LPCSTR: chuỗi được kết thúc bằng null không đổi của CHAR ( L ong P ointer)wchar_t: Ký tự 16 bit - kiểu dữ liệu C / C ++ cơ bảnWCHAR: bí danh của wchar_t- Kiểu dữ liệu WindowsLPWSTR: chuỗi được kết thúc bằng null của WCHAR ( L ong P ointer)LPCWSTR: chuỗi được kết thúc bằng null không đổi của WCHAR ( L ong P ointer)UNICODExác địnhTCHAR: bí danh của WCHARnếu UNICODE được xác định; nếu không thìCHARLPTSTR: chuỗi được kết thúc bằng null của TCHAR ( L ong P ointer)LPCTSTR: chuỗi được kết thúc bằng null không đổi của TCHAR ( L ong P ointer)Vì thế
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR→ Text Char ( archive.is )
Thêm vào câu trả lời của John và Tim.
Trừ khi bạn đang viết mã cho Win98, chỉ có hai trong số hơn 6 loại chuỗi mà bạn nên sử dụng trong ứng dụng của mình
LPWSTRLPCWSTRPhần còn lại nhằm hỗ trợ nền tảng ANSI hoặc biên dịch kép. Những điều đó ngày nay không còn phù hợp như trước đây nữa.
std::stringvì nó vẫn là một chuỗi dựa trên ASCII và std::wstringthay vào đó thích hơn .
*Aphiên bản của WinAPI tương thích với trang mã UTF-8, chúng đột nhiên phù hợp hơn rất nhiều. ; P
Để trả lời phần thứ hai của câu hỏi, bạn cần làm những việc như
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
bởi vì LVITEMcấu trúc của MS có một LPTSTR, tức là một con trỏ chuỗi T có thể thay đổi , không phải là một LPCTSTR. Những gì bạn đang làm là
1) chuyển đổi string(a CStringkhi đoán) thành một LPCTSTR(trong thực tế có nghĩa là lấy địa chỉ của bộ đệm ký tự của nó dưới dạng con trỏ chỉ đọc)
2) chuyển đổi con trỏ chỉ đọc đó thành một con trỏ có thể ghi bằng cách loại bỏ const-ness của nó .
Nó phụ thuộc vào những gì dispinfođược sử dụng để có hay không có khả năng ListViewcuộc gọi của bạn sẽ cố gắng viết thông qua đó hay không pszText. Nếu đúng như vậy, đây là một điều tiềm ẩn rất xấu: sau cùng thì bạn đã được cấp một con trỏ chỉ đọc và sau đó quyết định coi nó là có thể ghi: có thể có lý do khiến nó ở chế độ chỉ đọc!
Nếu đó là một CStringbạn đang làm việc với bạn, bạn có tùy chọn để sử dụng string.GetBuffer()- điều đó cố tình cung cấp cho bạn một quyền ghi LPTSTR. Sau đó, bạn phải nhớ gọi ReleaseBuffer()nếu chuỗi bị thay đổi. Hoặc bạn có thể cấp phát một bộ đệm tạm thời cục bộ và sao chép chuỗi vào đó.
99% thời gian điều này sẽ là không cần thiết và coi LPCTSTRnhư một LPTSTRcông việc sẽ làm ... nhưng một ngày nào đó, khi bạn ít mong đợi nhất ...
xxx_cast<>()thay thế.
xxx_cast<>thay vì trộn hai kiểu đúc dựa trên dấu ngoặc vuông khác nhau!