สิ่งที่แตกต่างระหว่างLPCSTR
, LPCTSTR
และLPTSTR
?
ทำไมเราต้องทำสิ่งนี้เพื่อแปลงสตริงเป็นตัวแปรLV
/ _ITEM
โครงสร้างpszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
สิ่งที่แตกต่างระหว่างLPCSTR
, LPCTSTR
และLPTSTR
?
ทำไมเราต้องทำสิ่งนี้เพื่อแปลงสตริงเป็นตัวแปรLV
/ _ITEM
โครงสร้างpszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
คำตอบ:
เพื่อตอบคำถามส่วนแรกของคุณ:
LPCSTR
เป็นตัวชี้ไปยังสตริง const (LP หมายถึงLong Pointer )
LPCTSTR
เป็นตัวชี้ไปยังconst TCHAR
สตริง ( TCHAR
เป็นอักขระแบบกว้างหรืออักขระแบบกว้างขึ้นอยู่กับว่า UNICODE ถูกกำหนดไว้ในโครงการของคุณหรือไม่)
LPTSTR
เป็นตัวชี้ไปยังTCHAR
สตริง(ไม่ใช่ const)
ในทางปฏิบัติเมื่อพูดถึงสิ่งเหล่านี้ในอดีตเราได้ทิ้งวลี "ตัวชี้ไปที่" ไว้เพื่อความเรียบง่าย แต่ตามที่กล่าวไว้โดยความสว่าง - การแข่งขันในวงโคจรนั้นเป็นตัวชี้ทั้งหมด
นี่เป็นบทความ codeprojectที่ยอดเยี่ยมที่อธิบายถึงสตริง C ++ (ดู 2/3 ทางลงสำหรับแผนภูมิเปรียบเทียบประเภทต่างๆ)
extern "C"
หรือมีการเชื่อมโยงผ่าน นอกเหนือจากนั้นใช่แล้วมันควรต้องมีบิต "ตัวชี้" หรือคำอธิบายเฉพาะเป็นสตริง C
รวดเร็วและสกปรก:
LP
== ล ong P ointer แค่คิดว่าตัวชี้หรือถ่าน *
C
= C onst ในกรณีนี้ฉันคิดว่าพวกเขาหมายถึงสตริงอักขระเป็น const ไม่ใช่ตัวชี้ที่เป็น const
STR
คือ สตริง
ใช้T
สำหรับอักขระแบบกว้างหรืออักขระ (TCHAR) ขึ้นอยู่กับตัวเลือกการคอมไพล์
char
: อักขระ 8 บิต - อ้างอิงประเภทข้อมูล C / C ++CHAR
: นามแฝงของchar
- ประเภทข้อมูล WindowsLPSTR
: สตริงที่สิ้นสุดด้วย null ของCHAR
( L ong P ointer)LPCSTR
: สตริงที่สิ้นสุดด้วย null คงที่ของCHAR
( L ong P ointer)wchar_t
: อักขระ 16 บิต - อ้างอิงประเภทข้อมูล C / C ++WCHAR
: นามแฝงของwchar_t
- ประเภทข้อมูล WindowsLPWSTR
: สตริงที่สิ้นสุดด้วย null ของWCHAR
( L ong P ointer)LPCWSTR
: สตริงที่สิ้นสุดด้วย null คงที่ของWCHAR
( L ong P ointer)UNICODE
กำหนดTCHAR
: นามแฝงของWCHAR
ถ้า UNICODE ถูกกำหนด; มิฉะนั้นCHAR
LPTSTR
: สตริงที่สิ้นสุดด้วย null ของTCHAR
( L ong P ointer)LPCTSTR
: สตริงที่สิ้นสุดด้วย null คงที่ของTCHAR
( L ong P ointer)ดังนั้น
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR
→ อักขระข้อความ ( archive.is )
เพิ่มคำตอบของ John และ Tim
หากคุณไม่ได้เข้ารหัสสำหรับ Win98 มีเพียงสองประเภทสตริง 6+ ที่คุณควรใช้ในแอปพลิเคชันของคุณ
LPWSTR
LPCWSTR
ส่วนที่เหลือมีไว้เพื่อรองรับแพลตฟอร์ม ANSI หรือการคอมไพล์แบบคู่ สิ่งเหล่านี้ไม่เกี่ยวข้องกันอย่างที่เคยเป็นมาในปัจจุบัน
std::string
เพราะมันยังคงเป็นสตริงที่ใช้ ASCII และชอบstd::wstring
แทน
*A
เวอร์ชันของ WinAPI เข้ากันได้กับหน้ารหัส UTF-8 พวกเขาก็มีความเกี่ยวข้องมากขึ้น ; P
ในการตอบคำถามส่วนที่สองคุณต้องทำสิ่งต่างๆเช่น
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
เพราะของ MS LVITEM
struct มีLPTSTR
กล่าวคือไม่แน่นอนชี้ T-สตริงไม่LPCTSTR
T-สตริงไม่ สิ่งที่คุณกำลังทำคือ
1) แปลงstring
(a CString
โดยเดา) เป็นLPCTSTR
(ซึ่งในทางปฏิบัติหมายถึงการรับที่อยู่ของบัฟเฟอร์อักขระเป็นตัวชี้แบบอ่านอย่างเดียว)
2) แปลงตัวชี้แบบอ่านอย่างเดียวนั้นให้เป็นตัวชี้ที่เขียนได้โดยการทิ้งค่าconst
-ness
ขึ้นอยู่กับสิ่งที่dispinfo
จะใช้ว่ามีโอกาสที่ListView
สายของคุณจะพยายามเขียนผ่านสิ่งนั้นpszText
หรือไม่ ถ้าเป็นเช่นนั้นนี่อาจเป็นสิ่งที่เลวร้ายมาก: หลังจากทั้งหมดคุณได้รับตัวชี้แบบอ่านอย่างเดียวจากนั้นจึงตัดสินใจที่จะถือว่ามันเขียนได้: อาจมีเหตุผลที่มันเป็นแบบอ่านอย่างเดียว!
หากเป็นCString
คุณกำลังทำงานกับคุณมีตัวเลือกในการใช้งานstring.GetBuffer()
ซึ่งจงใจให้คุณเขียนLPTSTR
ได้ จากนั้นคุณต้องจำไว้ว่าต้องโทรReleaseBuffer()
หากสตริงมีการเปลี่ยนแปลง หรือคุณสามารถจัดสรรบัฟเฟอร์ชั่วคราวในเครื่องและคัดลอกสตริงลงในนั้น
99% ของเวลานี้จะไม่จำเป็นและถือว่าLPCTSTR
เป็นไปได้LPTSTR
ผล ... แต่วันหนึ่งเมื่อคุณคาดหวังน้อยที่สุด ...
xxx_cast<>()
แทน
xxx_cast<>
มากกว่าการผสมรูปแบบการหล่อแบบยึดสองแบบที่แตกต่างกัน!