2012-09-22 15 views
8

के लिए स्पष्टीकरण की आवश्यकता है मेरे पास विंडोज 7 64 बिट पर माइक्रोसॉफ्ट विजुअल स्टूडियो 2010 है। (परियोजना गुण में "वर्ण सेट", "सेट नहीं" पर सेट है लेकिन हर सेटिंग एक ही उत्पादन होता है।)एक यूटीएफ -8 बनाम सीपीपी केस

स्रोत कोड:

using namespace std; 
    char const charTest[] = "árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP\n"; 
    cout << charTest; 
    printf(charTest); 
    if(set_codepage()) // SetConsoleOutputCP(CP_UTF8); // *1 
    cerr << "DEBUG: set_codepage(): OK" << endl; 
    else 
    cerr << "DEBUG: set_codepage(): FAIL" << endl; 
    cout << charTest; 
    printf(charTest); 

* 1: windows.h भोजनालयों चीजें भी शामिल है, तो मैं मैं इसे एक अलग सीपीपी से भी शामिल कर रहा हूं।

संकलित बाइनरी में स्ट्रिंग को सही यूटीएफ -8 बाइट अनुक्रम के रूप में शामिल किया गया है। अगर मैं chcp 65001 के साथ कंसोल को यूटीएफ -8 पर सेट करता हूं और type main.cpp जारी करता हूं, तो स्ट्रिंग सही तरीके से प्रदर्शित होती है।

D:\dev\user\geometry\Debug>chcp 
Active code page: 852 

D:\dev\user\geometry\Debug>listProcessing.exe 
├írv├şzt┼▒r┼Ĺ t├╝k├Ârf├║r├│g├ęp ├üRV├ŹZT┼░R┼É T├ťK├ľRF├ÜR├ôG├ëP 
├írv├şzt┼▒r┼Ĺ t├╝k├Ârf├║r├│g├ęp ├üRV├ŹZT┼░R┼É T├ťK├ľRF├ÜR├ôG├ëP 
DEBUG: set_codepage(): OK 
��rv��zt��r�� t��k��rf��r��g��p ��RV��ZT��R�� T��K��RF��R��G��P 
árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP 

कि पीछे स्पष्टीकरण क्या है:

टेस्ट (सांत्वना ल्युसिडा कंसोल फ़ॉन्ट का उपयोग करने के लिए सेट)? क्या मैं printf के रूप में काम करने के लिए किसी भी तरह cout पूछ सकता हूं?

लगाव

कई का कहना है कि Windows कंसोल UTF-8 वर्णों बिल्कुल समर्थन नहीं करता।

Hungarian and Cyrillic letters on console at the same time

(मेरे डिफ़ॉल्ट कंसोल: मैं हंगरी में हंगरी के पुरुष, मेरे Windows अंग्रेजी पर सेट है (तिथि प्रारूप को छोड़कर, वे हंगरी की तैयारी में हैं) और सिरिलिक अक्षरों अभी भी हंगेरी पत्र के साथ-साथ सही ढंग से प्रदर्शित कर रहे हैं हूँ कोडपेज CP852 है)

+0

संभावित डुप्लिकेट के बारे में सर्वोत्तम प्रथाओं के बारे में पाया जा सकता है [मैं एक std :: codecvt facet कैसे लिखूं?] (http: // stackoverflow.com/questions/ 2 9 71386/कैसे-करें-i-write-a-stdcodecvt-facet) –

+0

@ हंसपैसेंट मैं इसे वही मानता नहीं हूं। ऐसा लगता है, लेकिन 'cout' और' printf' के बीच अंतर स्पष्ट रूप से समझाता नहीं है। और मुझे कुछ भी बदलने के लिए 'cout' को बताने के लिए' codecvt' पहलू भी लिखना चाहिए? एक आसान तरीका होना चाहिए, मुझे आशा है कि ... – Notinlist

उत्तर

4

यहां अंतर यह है कि सी ++ रनटाइम और सी लाइब्रेरी सिस्टम लोकेल को कैसे संभालती है।

एसटीडी के साथ एक ही परिणाम प्राप्त करने के लिए :: अदालत आप std::ios::imbue विधि और std::locale

लेकिन utf-8 के साथ मुख्य मुद्दा कोशिश कर सकते हैं करेंगे और सी ++ वर्णित here

सी ++ 03 दो प्रकार प्रदान करता है स्ट्रिंग अक्षर का। डबल कोट्स के भीतर निहित पहला प्रकार, टाइप कॉन्स्ट चार के एक नल-टर्मिनेटेड सरणी का उत्पादन करता है। दूसरा प्रकार, जिसे एल "" के रूप में परिभाषित किया गया है, प्रकार की कॉन्स wchar_t की एक नल-टर्मिनेटेड सरणी उत्पन्न करता है, जहां wchar_t एक विस्तृत वर्ण है। न तो शाब्दिक प्रकार यूटीएफ -8, यूटीएफ -16, या किसी अन्य प्रकार के यूनिकोड एन्कोडिंग के साथ स्ट्रिंग अक्षर के लिए समर्थन प्रदान करता है।

तो फिर भी यह सभी कार्यान्वयन विशिष्ट है और इस प्रकार गैर पोर्टेबल है, क्योंकि मानक सी ++ आउटपुट धाराओं में से कोई भी utf-8 को समझ सकता है।

+0

strea क्या एन्कोडिंग एमएस समर्थन कार्यान्वयन परिभाषित किया गया है। मेरी लिनक्स मशीन पर एक डिफ़ॉल्ट iostream utf8 के साथ ठीक काम करता है। शायद कुछ सेटिंग या कुछ एपीआई कॉल है जो वह एक ही परिणाम प्राप्त करने के लिए विंडोज़ पर उपयोग कर सकते हैं। – Sqeaky

+0

मैं तब तक इंतजार नहीं कर सकता जब तक कि कई सी ++ 11 कार्यान्वयन उन प्रस्तावित स्ट्रिंग अक्षर जैसे यू 8, यू, और यू प्राप्त न करें। मैं एक अंतरराष्ट्रीय उत्पाद के साथ काम करता हूं और यह हमारे जीवन को इतना आसान बना देगा। – stinky472

+0

आप एक निर्मित लोकेल को ढूंढने में सक्षम हो सकते हैं जो यूटीएफ -8 को http://en.cppreference.com/w/cpp/locale/codecvt पर उदाहरण में देखा गया है या शायद आप 'codecvt_byname' का उपयोग करने का कोई तरीका ढूंढ सकते हैं ': http://en.cppreference.com/w/cpp/locale/codecvt_byname –

1

विंडोज़ पर, एकल-बाइट तारों को आम तौर पर ASCII, या कुछ 256-वर्ण कोडपृष्ठ के रूप में व्याख्या किया जाता है। इसका मतलब है कि आपको असली यूनिकोड समर्थन नहीं मिलेगा।

संक्षिप्त उत्तर है: विस्तृत तारों का उपयोग करें (उदा। L""árvíztűr..." - एल को नोटिस करें) cout के बजाय wcout पर लिखें। विंडोज आमतौर पर यूटीएफ -16 (या कम से कम एक करीबी संस्करण) के रूप में तारों (विंडोज़ पर 2 बाइट्स) स्ट्रिंग का अर्थ है, इसलिए यह इरादे के रूप में काम करेगा। विंडोज़ पर एन्कोडिंग समस्याओं से बचने के लिए हमेशा विस्तृत तारों का उपयोग करें।

+0

क्या wcout के साथ कोई समस्या नहीं है, जो आंतरिक रूप से यूनिकोड को CP_ACP में परिवर्तित करता है, और उसके बाद यूनिकोड पर वापस आ जाता है, ताकि वास्तव में wcout यूनिकोड का समर्थन न करे? – Dialecticus

+0

@ डायलेक्टिकस - wcout हमेशा मेरे लिए ठीक काम करता है। – AshleysBrain

+3

यह विंडोज कंसोल आउटपुट है जो यूटीएफ -8 के साथ काम करने में विफल रहता है (यह कंसोल के लिए वैध कोडपृष्ठ नहीं है)। इसके ऊपर सी ++ परत स्मार्ट चीज करने में असफल रही है। – rubenvb

1

सभी विंडोज़ कंसोल का पहला यूटीएफ -8 (कोडपेज 65001, का समर्थन करने के लिए यूटीएफ -8 एन्कोडेड फ़ाइल को खोलने के लिए समर्थन नहीं करता है जो कंसोल में नोटपैड से सहेजा गया है और आपको कंसोल में जंक डेटा दिखाई देगा), इसलिए अपने आउटपुट की जांच करने के लिए आपको इसे किसी फ़ाइल या उस तरह से कुछ पर रीडायरेक्ट करना चाहिए और वहां से परिणाम देखें (myapp> test.txt)।

सी/सी ++ char [] में दूसरा वर्ण उन वर्णों का अनुक्रम है जो प्रोग्रामर चाहते हैं, लेकिन यूटीएफ -8 यूनिकोड चरित्र सेट को एन्कोड करने के लिए एक विशेष प्रोटोकॉल है, इसलिए कोई रास्ता नहीं है (सी ++ 11 के बगल में)) कि आप अक्षरों का अनुक्रम और यूटीएफ 8 में एन्कोड किए गए उन अक्षरों को लिखते हैं क्योंकि मैं char p[3] = "اب" कहूंगा, लेकिन यदि कंपाइलर यूटीएफ -8 में इसे एन्कोड करना चाहता है तो इसे 5 बाइट्स 3 की आवश्यकता नहीं है। इसलिए आपको यूटीएफ -8 को समझने वाले कुछ का उपयोग करना चाहिए।

मैं व्यापक स्ट्रिंग स्थिरांक के साथ boost::locale::conv::utf_to_utf का उपयोग करने का सुझाव देता हूं। उदाहरण

std::string sUTF8 = boost::locale::conv::utf_to_utf(L"árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP\n"); 
std::cout << sUTF8; // or printf("%s", sUTF8.c_str()); 

के लिए इस, कंसोल के साथ यह जांच नहीं करते यह सुनिश्चित करेंगे कि आप UTF-8 स्ट्रिंग है कि है, लेकिन फिर से के बाद से यह बिल्कुल UTF-8 समझ में नहीं आता !!।

+0

आप गलत हैं। 'लुसीडा कंसोल' पर फ़ॉन्ट सेट करें, 'chcp 65001' जारी करें और देखें कि यूटीएफ -8 वर्ण सही ढंग से दिखाई देते हैं (केवल बाइट ऑर्डर चिह्न खाली आयताकार के रूप में दिखाई देता है)। मैंने इस पल में फिर से परीक्षण किया। ये कदम प्रश्न में शामिल हैं। – Notinlist

+0

मैं घर पर बाद में इस बूस्ट फ़ंक्शन का प्रयास करूंगा। उस संकेत के लिए धन्यवाद। – Notinlist

+0

मैंने जो कुछ कहा है, मैंने फ़ॉन्ट को 'लुसीडा कंसोल' पर सेट किया है और 'chcp 65001' जारी किया है, लेकिन यह केवल आयताकार दिखाता है, यदि आप उन्हें देख सकते हैं तो संभवतः क्योंकि आपके यूनिकोड फ़ाइल में आपके द्वारा उपयोग किए जाने वाले वर्ण CP_ACP से हैं (सिस्टम का डिफ़ॉल्ट कोड पृष्ठ जो नियंत्रण कक्ष के माध्यम से बदला जा सकता है)। जापानी या अन्य जैसी अन्य भाषाओं के पात्रों का उपयोग करें और आप देखेंगे कि कंसोल उन्हें – BigBoss

2

कमांड लाइन थोड़े मेरी समझ

  1. कमांड लाइन में UTF-8 वर्ण प्रदर्शित
  2. सही कोड पृष्ठ सेट करने में सक्षम एक फ़ॉन्ट (chcp के लिए UTF-8 के साथ काम प्रतीत होता है 65001) यकीन नहीं इस कोड को पेज पूर्ण UTF-8 वर्णों का समर्थन करता है, लेकिन यह

इसे देखें here और here

सबसे अच्छा उपलब्ध हो रहा है अगर

[संपादित करें] वास्तव में 65001 वास्तव में UTF-8 है के बाद मैं PowerShell

में जाँच
PS C:\Users\forcewill> chcp 65001 
Active code page: 65001 
PS C:\Users\forcewill> [Console]::OutputEncoding 


BodyName   : utf-8 
EncodingName  : Unicode (UTF-8) 
HeaderName  : utf-8 
WebName   : utf-8 
WindowsCodePage : 1200 
IsBrowserDisplay : True 
IsBrowserSave  : True 
IsMailNewsDisplay : True 
IsMailNewsSave : True 
IsSingleByte  : False 
EncoderFallback : System.Text.EncoderReplacementFallback 
DecoderFallback : System.Text.DecoderReplacementFallback 
IsReadOnly  : True 
CodePage   : 65001 

आप PowerShell इसकी अधिक शक्तिशाली तो पुराने cmd.exe

Edit: उपयोग कर सकते हैं अगर हम अदालत का उपयोग कर के बारे में विजुअल स्टूडियो में बात कर रहे सही जवाब here अधिक स्टूडियो स्पष्टीकरण here को विजुअल स्टूडियो

+0

इस उप-विषयक में मुझे समर्थन देने के लिए धन्यवाद, लेकिन मुख्य प्रश्न इस बारे में है यूटीएफ -8 अनुक्रमों को प्रदर्शित करने के लिए 'cout' का उपयोग करना। – Notinlist

+0

वास्तव में प्रश्न विजुअल स्टूडियो से भी संबंधित है, इसलिए मैंने विषय को शामिल करने के लिए अपनी प्रतिक्रिया अपडेट की है, दृश्य स्टूडियो में आपको windows.h शामिल करना चाहिए और प्रीप्रोसेसर मैक्रो यूनिकोड को परिभाषित करना चाहिए और स्थिर तारों की घोषणा करने के लिए एल मैक्रो का उपयोग करना है, यह समझाया गया है आखिरी लिंक में मैंने अब अपने Awnser में आपूर्ति की है, – forcewill

+0

कुछ चालें, लेकिन अभी तक चिकनी नहीं है। मैं कल इसे फिर से शुरू करूंगा। – Notinlist

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