2012-10-28 17 views
6

मैं C++ एक JSON पार्सर लिख रहा हूँ और जब JSON तार पार्स करने में कोई समस्या का सामना करना पड़ रहा हूँ:JSON तारों में यूनिकोड मानों को कैसे प्रबंधित करें?

JSON विनिर्देश कहा गया है कि JSON तार के रूप में यूनिकोड वर्ण हो सकते हैं:

"here comes a unicode character: \u05d9 !" 

मेरे JSON पार्सर JSON तारों को std::string पर मैप करने का प्रयास करता है, इसलिए आम तौर पर, JSON तारों का एक वर्ण std::string का एक चरित्र बन जाता है। हालांकि उन यूनिकोड वर्ण के लिए, मैं वास्तव में क्या करना है पता नहीं:

मैं सिर्फ इतना की तरह मेरे std::string में कच्चे बाइट्स मान रखना चाहिए:

std::string mystr; 
mystr.push_back('\0x05'); 
mystr.push_back('\0xd9'); 

या मैं एक साथ दो पात्रों की व्याख्या करना चाहिए लाइब्रेरी iconv और इसके बजाय मेरी स्ट्रिंग में यूटीएफ -8 एन्कोडेड परिणाम स्टोर करें?

क्या मुझे सभी पात्रों को स्टोर करने के लिए std::wstring का उपयोग करना चाहिए? फिर * NIX OSes पर जहां wchar_t 4-बाइट लंबा है?

मुझे लगता है कि मेरे समाधान में कुछ गलत है लेकिन मैं समझने में असफल रहा। मुझे उस स्थिति में क्या करना चाहिए?

+0

यदि wchar_t 4 बाइट लंबा है, तो आप केवल शून्य-विस्तार कर सकते हैं ... इसके अलावा, यूटीएफ -8 का मतलब 8-बिट वर्ण नहीं है। गैर-ASCII यूटीएफ -8 एन्कोडिंग में भी कई बाइट्स का उपयोग करके संग्रहीत किया जाएगा। –

+0

@ एच 2CO3: निश्चित रूप से, वास्तव में। http://json.org कहता है कि एक * स्ट्रिंग * में ** कोई यूनिकोड चरित्र हो सकता है ** लेकिन यह नहीं कहता कि वे तार यूटीएफ -8 या यूटीएफ -16 एनकोडेड हैं या नहीं। ऐसा लगता है कि यह यूटीएफ -8 अक्षरों के लिए एक विशेष प्रतिनिधित्व के साथ यूटीएफ -8 एन्कोडिंग है। मेरे प्रश्न का एक लक्ष्य यह सुनिश्चित करने के लिए भी है। – ereOn

+3

"यूटीएफ -16 अक्षरों" जैसी कोई चीज़ नहीं है। यूनिकोड वर्ण हैं जो एएससीआईआई का हिस्सा नहीं हैं, और वे यूटीएफ -8, यूटीएफ -16 और यूटीएफ -32 में कई बाइट्स का उपयोग करके एन्कोड किए गए हैं। यूटीएफ -16 और यूटीएफ -32 में मिश्रित-से-बहु-बाइट-वाइड-कैरेक्टर स्ट्रिंग्स सभी पात्रों को समान लंबाई के क्रम में jsut सुविधा हैं। –

उत्तर

11

कुछ खुदाई और H2CO3's comments और Philipp's comments करने के लिए धन्यवाद के बाद, मैं अंत में समझ सकते हैं कि यह कैसे काम करने के लिए माना जाता है:

RFC4627 पढ़ना, धारा 3. Encoding:

  1. एन्कोडिंग

    JSON टेक्स्ट यूनिकोड में एन्कोड किया जाएगा। डिफ़ॉल्ट एन्कोडिंग
    यूटीएफ -8 है।

    एक JSON पाठ के पहले दो अक्षर के बाद से हमेशा ASCII वर्ण [RFC0020] हो जाएगा, यह निर्धारित करने के लिए एक ओकटेट
    धारा UTF-8, UTF-16 (बीई या ले), या UTF है कि क्या संभव है पहले चार ऑक्टेट्स में नल के पैटर्न पर
    देखकर -32 (बीई या ली)।

    00 00 00 xx UTF-32BE 
        00 xx 00 xx UTF-16BE 
        xx 00 00 00 UTF-32LE 
        xx 00 xx 00 UTF-16LE 
        xx xx xx xx UTF-8 
    

तो ऐसा लगता है एक JSON ओकटेट धारा UTF-8 में एन्कोड किया जा सकता, UTF-16, या UTF-32 (दोनों अपने बीई में या ले, वेरिएंट पिछले दो के लिए)।

एक बार है कि स्पष्ट है, Section 2.5. Strings बताते हैं कि कैसे JSON तार में उन लोगों के \uXXXX मानों का प्रबंधन कैसे:

किसी भी चरित्र से बच गया हो सकता है। चरित्र बेसिक
बहुभाषी विमान (U + 0000 U + FFFF के माध्यम से) में है, तो यह
एक छह चरित्र अनुक्रम के रूप में प्रतिनिधित्व किया जा सकता है: एक रिवर्स सोलिडस छोटा अक्षर यू, जिसके बाद से पीछा
चार हेक्साडेसिमल अंक
चरित्र के कोड बिंदु को एन्कोड करें। हेक्साडेसिमल अक्षरों ए
एफ ऊपरी या लोअरकेस हो सकता है। इसलिए, उदाहरण के लिए,
युक्त एक स्ट्रिंग केवल एक एकल रिवर्स ठोस वर्ण को
"\ u005C" के रूप में दर्शाया जा सकता है।

Basic Multilingual Plane में वर्णों के लिए अधिक पूर्ण स्पष्टीकरण के साथ।

एक विस्तारित चरित्र है कि बेसिक बहुभाषी विमान में नहीं है से बचने के लिए, चरित्र एक बारह चरित्र अनुक्रम,
UTF-16 के किराए की जोड़ी एन्कोडिंग के रूप में प्रतिनिधित्व किया है। इसलिए, उदाहरण के लिए, एक स्ट्रिंग
जिसमें केवल जी क्लीफ वर्ण (यू + 1 डी 11 ई) शामिल है, को
"\ uD834 \ uDD1E" के रूप में दर्शाया जा सकता है।

उम्मीद है कि इससे मदद मिलती है।

+0

क्या आपको यह काम करने के लिए मिला? जब मैं अपने wstring को एल "{\" प्रकार \ ": \" स्ट्रिंग \ ", \" मान \ ": \" \\ u9CE5 \ "} के रूप में डालता हूं, \ n", wcout उस पंक्ति में आउटपुट के लिए \ u9CE5 दिखाता है । – Michele

2

यदि मैं आप थे, तो मैं केवल यूटीएफ -8 और यूटीएफ -8 स्टोर करने के लिए std :: string का उपयोग करूंगा। यदि आने वाले JSON टेक्स्ट में कोई \ uXXXX अनुक्रम नहीं है, तो std :: स्ट्रिंग का उपयोग किसी भी रूपांतरण के बिना बाइट टू बाइट के रूप में किया जा सकता है।

जब आप \ uXXXX पार्स करते हैं, तो आप इसे आसानी से डीकोड कर सकते हैं और इसे यूटीएफ -8 में परिवर्तित कर सकते हैं, प्रभावी रूप से इसका इलाज कर सकते हैं जैसे कि यह सही जगह पर यूटीएफ -8 चरित्र था - यही वह है जो अधिकांश JSON पार्सर्स वैसे भी कर रहे हैं (libjson पक्का)।

अनुमोदित, इस दृष्टिकोण के साथ JSON को \ uXXXX के साथ पढ़ने और तुरंत अपनी लाइब्रेरी का उपयोग करके इसे वापस डंप करने की संभावना है \ uXXXX अनुक्रमों को खोने और उन्हें अपने असली यूटीएफ -8 प्रस्तुतियों के साथ बदलने की संभावना है, लेकिन वास्तव में कौन परवाह करता है? आखिरकार, शुद्ध परिणाम अभी भी वही है।

+0

'\ u' एस्केप अनुक्रम यूटीएफ -16 कोड इकाइयों को इंगित करते हैं, इसलिए आप कम से कम दो भागने के दृश्यों को देखे बिना उन्हें बस डीकोड नहीं कर सकते हैं। – Philipp

+0

@ फिलिप: ऐसी शर्म भी ... वे बहुत करीब थे। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^