2012-08-20 21 views
9

में संगतता मैं एक प्रोग्राम लिख रहा हूं जिसे सभी भाषाओं में पाठ के साथ काम करने में सक्षम होना चाहिए। मेरी समझ यह है कि यूटीएफ -8 नौकरी करेगा, लेकिन मुझे इसके साथ कुछ समस्याएं आ रही हैं।यूटीएफ -8 सी ++

क्या मुझे यह कहना सही है कि यूटीएफ -8 को सी ++ में एक सरल char में संग्रहीत किया जा सकता है? यदि हां, तो मुझे निम्नलिखित चेतावनी क्यों मिलती है जब मैं char, string और stringstream: warning C4566: character represented by universal-character-name '\uFFFD' cannot be represented in the current code page (1252) के साथ प्रोग्राम का उपयोग करता हूं। (मुझे लगता है कि त्रुटि नहीं मिलता है जब मैं wchar_t, wstring और wstringstream का उपयोग करें।)

साथ ही, मुझे पता है कि UTF चर लंबाई है। जब मैं at या substr स्ट्रिंग विधियों का उपयोग करता हूं तो क्या मुझे गलत जवाब मिल जाएगा?

+0

यूटीएफ wchar_t के लिए भंडारण की सिफारिश की जाती है। आप यूटीएफ -8 को बिना किसी मुद्दे के चार में स्टोर कर सकते हैं लेकिन परिणाम अजीब होंगे। – perilbrain

+4

@ अनामित जो आपके प्लेटफॉर्म पर निर्भर करता है (और * * * जिसमें यूटीएफ का स्वाद है) में निर्भर करता है। विंडोज़ पर, 'wchar_t' यूटीएफ -16 के लिए एक अच्छा फिट है। लिनक्स पर, यूटीएफ -32 के लिए उपयोग करना उचित है। यूटीएफ -8 के लिए, 'char' एक बहुत ही उचित उम्मीदवार है (जब तक आपको C++ 11 में "नए" वर्ण प्रकारों तक पहुंच प्राप्त न हो) – jalf

+0

यह प्रोग्राम प्लेटफ़ॉर्म पर पोर्ट किया जाएगा। उस उद्देश्य के लिए किस चरित्र प्रकार का सबसे अच्छा उपयोग किया जा सकता है? – Qman

उत्तर

11

UTF-8 स्ट्रिंग शाब्दिक उपयोग करने के लिए आप उन्हें u8 साथ उपसर्ग करने की जरूरत है, अन्यथा आप कार्यान्वयन के चरित्र सेट प्राप्त (आपके मामले में, यह विंडोज़ -1252 प्रतीत हो रहा है) प्रतिस्थापन चरित्र (यू + एफएफएफडी) का यूटीएफ -8 प्रतिनिधित्व। इसमें char const[4] टाइप है।

चूंकि यूटीएफ -8 में चर की लंबाई है, इसलिए सभी प्रकार की इंडेक्सिंग कोड इकाइयों में इंडेक्सिंग करेगी, न कि कोडपॉइंट्स। यूटीएफ -8 अनुक्रम में कोडपॉइंट्स पर यादृच्छिक पहुंच करना संभव नहीं है क्योंकि इसकी परिवर्तनीय लंबाई प्रकृति है। यदि आप यादृच्छिक पहुंच चाहते हैं तो आपको एक निश्चित लंबाई एन्कोडिंग का उपयोग करने की आवश्यकता है, जैसे यूटीएफ -32। इसके लिए आप तारों पर U उपसर्ग का उपयोग कर सकते हैं।

+2

मैं अब तक उपसर्ग 'एल' का उपयोग कर रहा था। मैंने इसे 'u8' के साथ बदलने की कोशिश की लेकिन मुझे त्रुटि मिली' त्रुटि C2065: 'u8': अविकसित पहचानकर्ता '। – Qman

+1

@ user1563613 यह संभव है कि आपका कंपाइलर अभी तक 'u8' का समर्थन नहीं करता है। क्या यह विजुअल स्टूडियो है? यदि ऐसा है तो आपको शायद यूटीएफ -16 का उपयोग करना चाहिए, जो विंडोज एपीआई का उपयोग करता है। –

+0

यह विजुअल स्टूडियो 2010 है। यदि मैं यूटीएफ -16 का उपयोग करता हूं तो मुझे अंत्येष्टि निर्दिष्ट करना होगा, सही? यदि हां, तो क्या इस प्रोग्राम को अन्य प्लेटफॉर्म पर पोर्ट करते समय कोई समस्या नहीं होगी? – Qman

1

कारण आप चेतावनी मिलती है के बारे में \uFFFD है कि आप एक एकल बाइट के अंदर FF FD फिट करने के लिए, जैसा कि आप का उल्लेख किया, कोशिश कर रहे हैं के बाद से char रों के UTF-8 काम करता है और चर लंबाई है।

यदि आप at या substr का उपयोग करते हैं, तो आपको संभवतः गलत उत्तर मिलेंगे क्योंकि इन विधियों की गणना है कि एक बाइट एक वर्ण होना चाहिए। यह यूटीएफ -8 के मामले में नहीं है। विशेष रूप से, at के साथ, आप चरित्र अनुक्रम के एक बाइट के साथ समाप्त हो सकते हैं; substr के साथ, आप एक अनुक्रम तोड़ सकते हैं और एक अवैध यूटीएफ -8 स्ट्रिंग के साथ समाप्त हो सकते हैं (यह , \uFFFD के साथ शुरू या समाप्त होगा, वही जिसे आप स्पष्ट रूप से उपयोग करने का प्रयास कर रहे हैं, और टूटा हुआ चरित्र खो जाएगा)।

मैं अनुशंसा करता हूं कि आप यूनिकोड तारों को स्टोर करने के लिए wchar का उपयोग करें। चूंकि प्रकार कम से कम 16 बिट्स है, इसलिए कई सारे वर्ण एक "इकाई" में फिट हो सकते हैं। u8"\uFFFD" साथ बाइट्स की अशक्त-समाप्त अनुक्रम है:

+0

सबसे बुरा हिस्सा यह है कि यह एक प्रतिस्थापन चरित्र के साथ खत्म नहीं होगा। सबस्ट्रेट के साथ गलत जगह पर यूटीएफ -8 बाइट्स का अनुक्रम तोड़ने से केवल अमान्य अनुक्रम में परिणाम मिलता है। प्रतिस्थापन वर्ण प्राप्त करने के लिए आपको उन्हें मैन्युअल रूप से सत्यापित करने और उन्हें बदलने की आवश्यकता है। –

+0

@ आर। मार्टिन्हो फर्नांडीस, वास्तव में। हालांकि, मुझे विश्वास होगा कि जब तक उपयोगकर्ता को डेटा प्रस्तुत किया जाता है, तब तक ढेर की कुछ परत नौकरी कर लेती। (फिर भी, जैसा कि आपने देखा है, यह सी ++ प्रोग्राम में अनिश्चित नहीं रहेगा।) – zneak

+0

तो मैं सबस्ट्रिंग्स को ठीक से प्राप्त करने या पात्रों पर पुनरावृत्ति करने के बारे में कैसे जाउंगा? – Qman

9

हां, यूटीएफ -8 एन्कोडिंग का उपयोग चार, स्ट्रिंग और स्ट्रिंगस्ट्रीम के साथ किया जा सकता है। एक char में एक एकल यूटीएफ -8 कोड इकाई होगी, जिसमें से एक को यूनिकोड कोड बिंदु का प्रतिनिधित्व करने के लिए चार तक की आवश्यकता हो सकती है।

हालांकि, यूटीएफ -8 का उपयोग विशेष रूप से माइक्रोसॉफ्ट के कंपाइलर्स के साथ कुछ मुद्दे हैं। सी ++ कार्यान्वयन कई चीजों के लिए 'निष्पादन चरित्र सेट' का उपयोग करते हैं, जैसे एन्कोडिंग वर्ण और स्ट्रिंग अक्षर। वीसी ++ हमेशा सिस्टम लोकेल एन्कोडिंग को निष्पादन चरित्र सेट के रूप में उपयोग करते हैं, और विंडोज सिस्टम लोकेल एन्कोडिंग के रूप में यूटीएफ -8 का समर्थन नहीं करता है, इसलिए यूटीएफ -8 निष्पादन चरित्र सेट द्वारा कभी नहीं हो सकता है।

इसका मतलब है कि वीसी ++ जानबूझकर यूटीएफ -8 चरित्र और स्ट्रिंग अक्षर का उत्पादन नहीं करता है। इसके बजाय संकलक धोखा दिया जाना चाहिए।

कंपाइलर ज्ञात स्रोत कोड एन्कोडिंग से निष्पादन एन्कोडिंग में परिवर्तित हो जाएगा। इसका अर्थ यह है कि यदि संकलक स्रोत और निष्पादन एन्कोडिंग दोनों के लिए लोकेल एन्कोडिंग का उपयोग करता है तो कोई रूपांतरण नहीं किया जाता है।आप स्रोत कोड में UTF-8 डेटा प्राप्त लेकिन संकलक है लगता है कि स्रोत स्थान एन्कोडिंग का उपयोग करता सकते हैं, तो चरित्र और स्ट्रिंग शाब्दिक UTF-8 एन्कोडिंग का प्रयोग करेंगे। स्रोत एन्कोडिंग का पता लगाने के लिए वीसी ++ तथाकथित 'बीओएम' का उपयोग करता है, और यदि कोई बीओएम नहीं पता चला है तो लोकेल एन्कोडिंग का उपयोग करता है। इसलिए आप अपनी सभी स्रोत फ़ाइलों को "हस्ताक्षर किए बिना यूटीएफ -8" के रूप में सहेजकर यूटीएफ -8 एन्कोडेड स्ट्रिंग अक्षर प्राप्त कर सकते हैं।

इस विधि के साथ चेतावनियां हैं। सबसे पहले, आप संकीर्ण चरित्र और स्ट्रिंग अक्षर के साथ यूसीएन का उपयोग नहीं कर सकते हैं। यूनिवर्सल कैरेक्टर नेम को निष्पादन चरित्र सेट में परिवर्तित करना होगा, जो यूटीएफ -8 नहीं है। आपको या तो अक्षर को अक्षरशः लिखना चाहिए ताकि यह स्रोत कोड में यूटीएफ -8 के रूप में दिखाई दे, या आप हेक्स एस्केप का उपयोग कर सकते हैं जहां आप मैन्युअल रूप से यूटीएफ -8 एन्कोडिंग लिखते हैं। दूसरा, आदेश विस्तृत चरित्र और स्ट्रिंग शाब्दिक निर्माण करने के लिए संकलक विस्तृत निष्पादन वर्ण सेट करने के लिए स्रोत एन्कोडिंग से एक ऐसी ही रूपांतरण करता (जो हमेशा कुलपति में UTF-16 है ++)। चूंकि हम एन्कोडिंग के बारे में कंपाइलर से झूठ बोल रहे हैं, यह इस रूपांतरण को यूटीएफ -16 में गलत तरीके से करेगा। तो विस्तृत चरित्र और स्ट्रिंग अक्षर में आप गैर-एसीआई अक्षरों का शाब्दिक रूप से उपयोग नहीं कर सकते हैं, और इसके बजाय आपको यूसीएन या हेक्स भागने का उपयोग करना होगा।


UTF-8 चर लंबाई है (के रूप में UTF-16 है)। at() और substr() के साथ प्रयोग किया सूचकांक कोड इकाइयों बजाय चरित्र या कोड बिंदु सूचकांक कर रहे हैं। तो यदि आप एक विशेष कोड इकाई चाहते हैं तो आप केवल स्ट्रिंग या सरणी या सामान्य के रूप में जो भी हो सकते हैं। आप एक विशेष कोड बिंदु की जरूरत है तो आप या तो एक पुस्तकालय है कि कोड अंक में UTF-8 कोड इकाइयों रचना (जैसे बूस्ट Unicode iterators library के रूप में) को समझ सकते हैं की जरूरत है, या आप UTF-32 में UTF-8 डेटा कन्वर्ट करने के लिए की जरूरत है। यदि आपको वास्तविक उपयोगकर्ता कथित वर्णों की आवश्यकता है तो आपको एक लाइब्रेरी की आवश्यकता है जो समझता है कि वर्ण बिंदुओं में कोड बिंदु कैसे बनाये जाते हैं। मुझे लगता है कि आईसीयू की ऐसी कार्यक्षमता है, या आप यूनिकोड मानक से Default Grapheme Cluster Boundary Specification को कार्यान्वित कर सकते हैं।


UTF-8 के ऊपर विचार केवल वास्तव में कैसे आप स्रोत कोड में यूनिकोड डेटा लिखने के लिए मायने रखती है। कार्यक्रम के इनपुट और आउटपुट पर इसका थोड़ा असर पड़ता है।

अपनी आवश्यकताओं को आप कैसे इनपुट और आउटपुट करने के लिए तो मैं अभी भी निवेश के लिए UTF-8 का उपयोग कर की सिफारिश करेंगे चयन करने की अनुमति है। इनपुट के साथ आपको क्या करने की आवश्यकता है इसके आधार पर आप इसे किसी अन्य एन्कोडिंग में परिवर्तित कर सकते हैं जो आपके लिए प्रक्रिया करना आसान है, या आप सीधे यूटीएफ -8 पर काम करने के लिए अपनी प्रसंस्करण दिनचर्या लिख ​​सकते हैं।

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