2008-11-11 13 views
5

यूनिकोड स्ट्रिंग को utf-8 या utf-16 स्ट्रिंग में कैसे परिवर्तित करें? मेरे VS2005 परियोजना, यूनिकोड वर्ण सेट का उपयोग कर रहा है, जबकि सीपीपी में SQLite एक फ़ोल्डर खोलने के लिएयूनिकोड स्ट्रिंग को utf-8 या utf-16 स्ट्रिंग में कैसे परिवर्तित करें?

int sqlite3_open(
    const char *filename, /* Database filename (UTF-8) */ 
    sqlite3 **ppDb   /* OUT: SQLite db handle */ 
); 
int sqlite3_open16(
    const void *filename, /* Database filename (UTF-16) */ 
    sqlite3 **ppDb   /* OUT: SQLite db handle */ 
); 

प्रदान करते हैं। मैं स्ट्रिंग, सीएसटींग, या wstring को यूटीएफ -8 या यूटीएफ -16 वर्णसेट में कैसे परिवर्तित कर सकता हूं?

बहुत बहुत धन्यवाद!

उत्तर

6

लघु जवाब:

कोई रूपांतरण करता है, तो आप इस तरह के cstring या wstring के रूप में यूनिकोड तार का उपयोग की आवश्यकता है। Sqlite3_open16() का प्रयोग करें। आपको यह सुनिश्चित करना होगा कि आप एक डब्ल्यूसीएचएआर पॉइंटर पास करें (void * पर डाला गया। लंगड़ा लगता है! भले ही यह lib क्रॉस प्लेटफार्म है, मुझे लगता है कि वे एक विस्तृत चार प्रकार को परिभाषित कर सकते हैं जो मंच पर निर्भर करता है और void * से कम असभ्य है) एपीआई के लिए। एक cstring के लिए के रूप में इस तरह के: (void*)(LPCWSTR)strFilename

लंबा उत्तर:

आप एक यूनिकोड स्ट्रिंग है कि आप UTF8 या UTF16 को परिवर्तित करना चाहते हैं नहीं है। आपके पास दिए गए एन्कोडिंग का उपयोग करके आपके प्रोग्राम में एक यूनिकोड स्ट्रिंग का प्रतिनिधित्व किया गया है: यूनिकोड प्रति बाइनरी प्रतिनिधित्व नहीं है। एन्कोडिंग्स का कहना है कि कैसे यूनिकोड कोड पॉइंट्स (संख्यात्मक मान) स्मृति में प्रदर्शित होते हैं (संख्या का बाइनरी लेआउट)। यूटीएफ 8 और यूटीएफ 16 सबसे व्यापक रूप से उपयोग किए जाने वाले एन्कोडिंग हैं। हालांकि वे बहुत अलग हैं।

जब एक वीएस प्रोजेक्ट "यूनिकोड वर्णसेट" कहता है, तो इसका वास्तव में अर्थ है "वर्ण यूटीएफ 16 के रूप में एन्कोड किए गए हैं"। इसलिए, आप सीधे sqlite3_open16() का उपयोग कर सकते हैं। कोई रूपांतरण आवश्यक नहीं है। अक्षरों को WCHAR प्रकार में संग्रहीत किया जाता है (char के विपरीत) जो 16 बिट्स (मानक सी प्रकार wchar_t पर फॉल्सबैक लेता है, जो Win32 पर 16 बिट्स लेता है। अन्य प्लेटफार्मों पर अलग हो सकता है। सुधार के लिए धन्यवाद, चेकर्स)।

एक और विवरण है कि आप इस पर ध्यान देना चाहेंगे: यूटीएफ 16 2 स्वादों में मौजूद है: बिग एंडियन और लिटिल एंडियन। यह 16 बिट्स का बाइट ऑर्डरिंग है। यूटीएफ 16 के लिए आप जो फ़ंक्शन प्रोटोटाइप देते हैं वह यह नहीं कहता कि किस ऑर्डरिंग का उपयोग किया जाता है। लेकिन आप यह मानते हुए बहुत सुरक्षित हैं कि स्क्लाइट विंडोज के रूप में एक ही एंडियन-नेस का उपयोग करता है (लिटिल एंडियन आईआईआरसी। मुझे ऑर्डर पता है लेकिन हमेशा नामों में समस्या है :-))। चेकर्स द्वारा टिप्पणी करने के लिए उत्तर::

संपादित

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

वैसे ही एक यूटीएफ 8 1 से 4 बाइट अनुक्रम का उपयोग करके 1 वर्ण का प्रतिनिधित्व करता है। फिर भी यूटीएफ 8 का उपयोग char प्रकार के साथ किया जाता है।

+3

नहीं, नहीं, नहीं! sqlite3_open16() 'शून्य *' तर्क का उपयोग करता है, क्योंकि इसे यूटीएफ 16, * नहीं * wchar_t कहा जाता है, जो अलग-अलग प्लेटफॉर्म पर अलग-अलग आकार का होता है और हो सकता है कि यूटीएफ 16 (यानी glibc में 4-बाइट wchar_t) हो या हो। –

+0

चेकर्स: –

+1

से ऊपर संपादित करें के रूप में मेरा उत्तर देखें हाँ, मुझे यूटीएफ 16 प्रतिनिधित्व के बारे में पता है। लेकिन, आप यह नहीं मान सकते कि wchar_t का आंतरिक प्रतिनिधित्व सभी प्लेटफॉर्म पर समान है, यह नहीं है। –

7

WideCharToMultiByte फ़ंक्शन का उपयोग करें। CodePage पैरामीटर के लिए CP_UTF8 निर्दिष्ट करें।

CHAR buf[256]; // or whatever 
WideCharToMultiByte(
    CP_UTF8, 
    0, 
    StringToConvert, // the string you have 
    -1, // length of the string - set -1 to indicate it is null terminated 
    buf, // output 
    __countof(buf), // size of the buffer in bytes - if you leave it zero the return value is the length required for the output buffer 
    NULL,  
    NULL 
); 

इसके अलावा, खिड़कियों में यूनिकोड क्षुधा के लिए डिफ़ॉल्ट एन्कोडिंग तो आप किसी भी अनुवाद प्रदर्शन करने के लिए और सिर्फ दूसरे संस्करण sqlite3_open16 का उपयोग की आवश्यकता न पड़े, UTF-16LE है।

+0

मैं एक निश्चित बफर की अनुशंसा नहीं करता; इसके बजाए, एक गतिशील रूप से आवंटित बफर (उदा।, std :: वेक्टर) का उपयोग करें, आवश्यकतानुसार विस्तार (जब वाइडचारटोमल्टी बाइट आपको बताता है कि आपकी स्ट्रिंग बहुत छोटी है)। –

+1

मुझे असहमत होना है: आप दिखाते हैं कि यूटीएफ 16 से यूटीएफ 8 में कैसे परिवर्तित करें। ओपी की आवश्यकता नहीं है क्योंकि व्यापक चार तारों के लिए एक समारोह उपलब्ध है: sqlite3_open16()। आईएमओ, सही जवाब है: sqlite3_open16() का उपयोग करें। –

+0

@ क्रिस यही कारण है कि मैंने "या जो भी" कहा और आउटपुट बफर आकार पर टिप्पणी डाली - मैं मामलों को बहुत जटिल नहीं करना चाहता था –

0

utf-8 और utf-16 दोनों "यूनिकोड" वर्ण एन्कोडिंग हैं। आप शायद यूटीएफ -32 के बारे में क्या बात करते हैं जो एक निश्चित आकार के चरित्र एन्कोडिंग है। हो सकता है कि के लिए

"Convert utf-32 into utf-8 or utf-16"

खोज आप इस पर कुछ परिणाम या अन्य कागजात प्रदान करता है।

3

सभी सी ++ स्ट्रिंग प्रकार वर्णमाला तटस्थ हैं। वे सिर्फ एक चरित्र चौड़ाई पर बसते हैं, और कोई और धारणा नहीं करते हैं। एक wstring विंडोज में 16-बिट वर्णों का उपयोग करता है, जो लगभग utf-16 के अनुरूप है, लेकिन यह अभी भी थ्रेड में संग्रहीत करने पर निर्भर करता है। Wstring किसी भी तरह से लागू नहीं करता है कि आपके द्वारा डाला गया डेटा मान्य utf16 होना चाहिए। विंडोज़ यूटीएफ 16 का उपयोग करता है जब यूनिकोड को परिभाषित किया जाता है, इसलिए संभवतः आपके तार पहले से ही utf16 हैं, और आपको कुछ भी करने की आवश्यकता नहीं है।

कुछ अन्य ने वाइडरहर्टोमल्टी बाइट फ़ंक्शन का उपयोग करने का सुझाव दिया है, जो utf16 को utf8 में परिवर्तित करने के लिए जाने के तरीके (में से) है। लेकिन चूंकि स्क्लाइट utf16 को संभाल सकता है, जो आवश्यक नहीं होना चाहिए।

0

ऐसा करने का सबसे आसान तरीका CStringA का उपयोग करना है। सीएसटींग क्लास CSTringA (ASCII संस्करण) या CStringW (विस्तृत चार संस्करण) के लिए एक टाइपिफ़ है। इन दोनों कक्षाओं में स्ट्रिंग प्रकारों को बदलने के लिए निर्माता हैं। मैं आम तौर पर उपयोग करता हूं:

sqlite3_open(CStringA(L"MyWideCharFileName"), ...); 
संबंधित मुद्दे