LPCSTR, LPCTSTR और LPTSTR


109

क्या अंतर है LPCSTR, LPCTSTRऔर LPTSTR?

हमें स्ट्रिंग को LV/ _ITEMसंरचना चर में बदलने के लिए ऐसा करने की आवश्यकता क्यों है pszText:

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

2
क्या आप वास्तव में कह सकते हैं कि "स्ट्रिंग" किस प्रकार की है? (उदा। सीएसटीरिंग)
जॉन सोबेल

जवाबों:


122

अपने प्रश्न के पहले भाग का उत्तर देने के लिए:

LPCSTRएक कास्ट स्ट्रिंग के लिए एक सूचक है (एलपी का मतलब है लॉन्ग पॉइंटर )

LPCTSTRएक const TCHARस्ट्रिंग के लिए एक संकेतक है , ( TCHARUNICODE को आपकी परियोजना में परिभाषित किया गया है या नहीं, इस आधार पर एक विस्तृत वर्ण या चार्ट है)

LPTSTRएक (नॉन-कास्ट) TCHARस्ट्रिंग के लिए एक संकेतक है

व्यवहार में जब अतीत में इन के बारे में बात करते हैं, तो हमने "पॉइंटर को" सादगी के लिए वाक्यांश के लिए छोड़ दिया है, लेकिन जैसा कि लपट-दौड़-इन-ऑर्बिट द्वारा उल्लेख किया गया है, वे सभी संकेत हैं।

यह C ++ स्ट्रिंग्स का वर्णन करने वाला एक बेहतरीन कोडप्रोजेक्ट लेख है (विभिन्न प्रकारों की तुलना करने वाले चार्ट के लिए नीचे २/३ देखें)


18
सब गलत। इनमें से कोई भी चीज तार नहीं है। वे सभी संकेत हैं। -1
को ऑर्बिट में लाइटनेस दौड़

8
@LightnessRacesinOrbit आप तकनीकी रूप से सही कर रहे हैं - हालांकि मेरे अनुभव में यह आम बात बाहर छोड़ने के लिए है "एक सूचक ...." संक्षिप्तता के लिए विवरण जब C ++ स्ट्रिंग प्रकार की चर्चा करते हुए
जॉन Sibly

2
@ जॉन: सी में, हाँ। C ++ में, यह बिल्कुल नहीं होना चाहिए !!
ऑर्बिट

4
ध्यान दें कि कोडप्रोजेक्ट लेख 15 साल पहले लिखा गया था और जब तक यह अपडेट नहीं हो जाता, इसमें यूनिकोड वर्णों के बारे में भ्रामक धारणाएं होती हैं, जो हमेशा 2 बाइट्स होती हैं। यह पूरी तरह से गलत है। यहां तक ​​कि UTF16 चर लंबाई है ... यह कहना बेहतर है कि विस्तृत वर्ण UCS-2 एन्कोडेड हैं, और इस संदर्भ में "यूनिकोड" UCS-2 को संदर्भित करता है।
u8it

1
हम्म ... इस मामले में, @LightnessRacesinOrbit, मैं एक परिशिष्ट जोड़ूंगा कि जब C ++ में C- स्ट्रिंग्स का जिक्र हो, तो "पॉइंटर टू ..." छोड़ना ठीक है, अगर-और-केवल-विशेष रूप से संदर्भित हो तो (क्षय) स्ट्रिंग शाब्दिक, या जब कोड के साथ इंटरफेस / काम करना जो कि या तो सी में लिखा गया है, सी ++ प्रकारों के बजाय सी प्रकारों पर निर्भर करता है, और / या सी लिंकेज के माध्यम से होता है extern "C"। इसके अलावा, हाँ, यह निश्चित रूप से या तो "पॉइंटर" बिट या सी स्ट्रिंग के रूप में विशिष्ट विवरण की आवश्यकता होनी चाहिए।
जस्टिन टाइम - मोनिका

87

जल्दी और गन्दी:

LP== एल ओंग पी ओइंटर। बस पॉइंटर या चार सोचो *

C= सी onst, इस मामले में, मुझे लगता है कि उनका मतलब है कि चरित्र स्ट्रिंग एक कास्ट है, न कि पॉइंटर कांस्टेबल।

STRहै स्ट्रिंग

Tएक विस्तृत चरित्र या चार (TCHAR) संकलन विकल्पों के आधार पर के लिए है।


16
टी व्यापक चरित्र के लिए नहीं है, यह अलग-अलग चरित्र प्रकार के लिए है। W चौड़ी (WCHAR की तरह) है। यदि UNICODE को परिभाषित किया जाता है, तो TCHAR == WCHAR, अन्यथा TCHAR == CHAR। इसलिए यदि UNICODE परिभाषित नहीं है, तो LPCTSTR == LPCSTR।
जालपा

10
यही कारण है कि मैंने लिखा है "संकलन विकल्पों पर निर्भर करता है"
टिम

14
मैं वास्तव में इस प्रकार की व्याख्या से प्यार करता हूं :)। बहुत बहुत धन्यवाद
Dzung Nguyen

@ जैलफ, तो टी किस लिए खड़ा होता है?
पचेरियर


36

8-बिट AnsiStrings

  • char: 8-बिट वर्ण - अंतर्निहित C / C ++ डेटा प्रकार
  • CHAR: alias of char- विंडोज डेटा प्रकार
  • LPSTR: ( एल ओंग पी ओइंटर) की अशक्त-समाप्त स्ट्रिंगCHAR
  • LPCSTR: ( एल ओंग पी ओइंटर) का निरंतर अशक्त-समाप्त स्ट्रिंगCHAR

16-बिट यूनिकोडस्ट्रीम

  • wchar_t: 16-बिट वर्ण - अंतर्निहित C / C ++ डेटा प्रकार
  • WCHAR: alias of wchar_t- विंडोज डेटा प्रकार
  • LPWSTR: ( एल ओंग पी ओइंटर) की अशक्त-समाप्त स्ट्रिंगWCHAR
  • LPCWSTR: ( एल ओंग पी ओइंटर) का निरंतर अशक्त-समाप्त स्ट्रिंगWCHAR

UNICODEपरिभाषित पर निर्भर करता है

  • TCHAR: WCHARयदि उर्फ को परिभाषित किया जाता है, तो अन्य ; अन्यथाCHAR
  • LPTSTR: ( एल ओंग पी ओइंटर) की अशक्त-समाप्त स्ट्रिंगTCHAR
  • LPCTSTR: ( एल ओंग पी ओइंटर) का निरंतर अशक्त-समाप्त स्ट्रिंगTCHAR

इसलिए

| Item              | 8-bit        | 16-bit      | Varies          |
|-------------------|--------------|-------------|-----------------|
| character         | CHAR         | WCHAR       | TCHAR           |
| string            | LPSTR        | LPWSTR      | LPTSTR          |
| string (const)    | LPCSTR       | LPCWSTR     | LPCTSTR         |

बोनस पढ़ना

TCHARटेक्स्ट चार ( संग्रह। )


4
यह जवाब शर्म की बात है कि यह शीर्ष पर कभी नहीं होगा क्योंकि यह बहुत नया है .. यह वास्तव में कुछ है तो ठीक करने की आवश्यकता है। यह अब तक का सबसे अच्छा जवाब है।
दान बेचार

यह वास्तव में मुझे बहुत मदद करता है जब मैं काम पर यूनिकोड परियोजना कर रहा हूं। धन्यवाद!
यून ५

अच्छा उत्तर। मुझे लगता है कि यह जोड़ने योग्य है कि यूनिकोड संस्करण UTF16 का उपयोग करता है, इसलिए प्रत्येक 16-बिट चंक एक चरित्र नहीं बल्कि एक कोड-इकाई है। नाम ऐतिहासिक हैं (जब यूनिकोड === यूसीएस 2)।
मार्गरेट ब्लूम

5

जॉन और टिम के जवाब में जोड़ना।

जब तक आप Win98 के लिए कोडिंग नहीं कर रहे हैं, आपके आवेदन में उपयोग किए जा रहे 6+ स्ट्रिंग प्रकारों में से केवल दो हैं

  • LPWSTR
  • LPCWSTR

बाकी एएनएसआई प्लेटफॉर्म या दोहरे संकलन का समर्थन करने के लिए हैं। वे आज उतने प्रासंगिक नहीं हैं जितने पहले हुआ करते थे।


2
@ बालूराज, मैं मुख्य रूप से अपने उत्तर में सी आधारित स्ट्रिंग्स का उल्लेख कर रहा था। लेकिन C ++ के लिए मैं बचूंगा std::stringक्योंकि यह अभी भी एक ASCII आधारित स्ट्रिंग है और std::wstringइसके बजाय पसंद करते हैं।
जेरेडपर

1
आपको LPTSTR और LPCTSTR का उपयोग तब तक करना चाहिए जब तक कि आप सीधे ASCII (* A) या कार्यों के चौड़ी (* W) संस्करणों को नहीं बुला रहे हों। जब आप संकलित करते हैं, तो आप जो भी वर्ण चौड़ाई निर्दिष्ट करते हैं, वे उपनाम हैं।
ऑसविन

... और अब जब Microsoft *AUTAP-8 कोड पृष्ठ के साथ WinAPI के संस्करणों को बनाने पर काम कर रहा है , तो वे अचानक बहुत अधिक प्रासंगिक हो जाते हैं। ; पी
जस्टिन टाइम -

4

अपने प्रश्न के दूसरे भाग का उत्तर देने के लिए, आपको चीजों को करने की आवश्यकता है

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

क्योंकि MS की LVITEMसंरचना में LPTSTRa, यानी एक उत्परिवर्ती T- स्ट्रिंग सूचक है, न कि a LPCTSTR। आप जो कर रहे हैं, वह है

1) कन्वर्ट string(एक CStringअनुमान पर) एक में LPCTSTR(जो व्यवहार में इसका मतलब है कि केवल पढ़ने के लिए पॉइंटर के रूप में इसके चरित्र बफर का पता प्राप्त करना)

2) उस रीड-ओनली पॉइंटर को राइट-पॉइंटर में कन्वर्ट करके उसकी const-नेस को दूर कर दें ।

यह निर्भर करता है कि क्या dispinfoहै या नहीं, इस बात की संभावना है कि आपके है के लिए प्रयोग किया जाता है ListViewकॉल करने की कोशिश कर खत्म हो जाएगा लिखने कि के माध्यम से pszText। यदि ऐसा होता है, तो यह संभावित रूप से बहुत बुरी बात है: आखिरकार आपको एक रीड-ओनली पॉइंटर दिया गया और फिर इसे राइट करने योग्य माना गया: हो सकता है कि केवल पढ़ने-लिखने का कारण हो!

अगर यह CStringआप के साथ काम कर रहे हैं तो आपके पास उपयोग करने का विकल्प है string.GetBuffer()- जो जानबूझकर आपको एक लेखन योग्य बनाता है LPTSTR। आपको तब कॉल करने के लिए याद रखना होगा ReleaseBuffer()अगर स्ट्रिंग बदल जाती है। या आप एक स्थानीय अस्थायी बफर आवंटित कर सकते हैं और स्ट्रिंग को वहां कॉपी कर सकते हैं।

99% इस समय अनावश्यक होगा और LPCTSTRएक के रूप में इलाज LPTSTRकरना काम करेगा ... लेकिन एक दिन, जब आप कम से कम इसकी उम्मीद करते हैं ...


1
आपको सी स्टाइल कास्ट से बचना चाहिए और xxx_cast<>()इसके बजाय उपयोग करना चाहिए।
हार्पर

@harper आप काफी सही हैं - लेकिन मैं ओपी को उद्धृत कर रहा था, वह वह कोड है जिसके बारे में वह पूछ रहा था। अगर मैंने कोड खुद लिखा है तो यह xxx_cast<>दो अलग-अलग ब्रैकेट-आधारित कास्टिंग शैलियों को मिश्रण करने के बजाय निश्चित रूप से उपयोग किया जाएगा !
AAT
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.