2012-04-29 9 views
7

का उपयोग कर printf और खिड़कियों सांत्वना के तहत std :: ostream के बीच अलग है मैं एक प्रोग्राम है जो कंसोल के लिए UTF-8 स्ट्रिंग प्रिंट:क्या UTF-8 उत्पादन

#include <stdio.h> 

int main() 
{ 
    printf("Мир Peace Ειρήνη\n"); 
    return 0; 
} 

मैं कंसोल कॉन्फ़िगर सच उपयोग करने के लिए फोंट (ल्युसिडा कंसोल) टाइप करें, UTF-8 कोड-पेज (chcp 65001) को परिभाषित दोनों MinGW जीसीसी और विजुअल स्टूडियो 2010 यह पूरी तरह से काम करता है के साथ इस कार्यक्रम संकलन, मैं देख रहा हूँ: उत्पादन:

Мир Peace Ειρήνη 

मैं भी ऐसा ही std::cout

का उपयोग करना
#include <iostream> 

int main() 
{ 
    std::cout << "Мир Peace Ειρήνη\n" ; 
    return 0; 
} 

यह मिनीजीडब्ल्यू जीसीसी का उपयोग करते हुए उपर्युक्त रूप से ठीक काम करता है लेकिन विजुअल स्टूडियो 2010 के साथ मुझे वर्ग मिलते हैं, वर्गों से अधिक (प्रत्येक गैर-ASCII पत्र प्रति दो)।

यदि मैं रीडायरेक्शन test >test.txt के साथ प्रोग्राम चलाता हूं तो मुझे फ़ाइल में सही यूटीएफ -8 आउटपुट मिलता है।

दोनों परीक्षण विंडोज पर किया 7.

सवाल:

  1. उत्पादन धारा की हैंडलिंग में दृश्य स्टूडियो मानक पुस्तकालय में printf और std :: अदालत में क्या अंतर है - स्पष्ट रूप से उनमें से एक काम करता है और अन्य नहीं करता है?
  2. यह कैसे तय किया जा सकता है?

रियल उत्तर:

संक्षेप में: आप खराब कर रहे - std::cout वास्तव में MSVC + UTF-8 के साथ काम नहीं करता है - या कम से कम वह उचित रूप से व्यवहार करते हैं बनाने के लिए भारी प्रयास की आवश्यकता है।

लंबे समय में: उत्तर में संदर्भित दो लेख पढ़ें।

+0

यह आपके स्रोत कोड में सीधे यूनिकोड एम्बेड करने के लिए सुरक्षित नहीं है AFAIK। मेरा मानना ​​है कि सबसे सुरक्षित तरीका किसी प्रकार के संसाधन का उपयोग करना है या यूनिकोड कोड बिंदुओं को इनपुट करने के लिए \ u और u8 literal (C++ 11) –

+0

printf() है जो यूनिकोड और std :: cout आउटपुट करता है [ सी ++ में यूनिकोड समस्याएं लेकिन सी नहीं) (http://stackoverflow.com/questions/21370710) – Salvador

उत्तर

1

आप दोषपूर्ण मान्यताओं की एक संख्या है, lemme को सही उन पहले:

  • बातें जी ++ कि जी ++ ठीक से काम करता मतलब यह नहीं है के साथ काम करने के लिए प्रकट है।

  • विजुअल स्टूडियो एक कंपाइलर नहीं है, यह एक आईडीई है जो कई भाषाओं और कंपाइलरों का समर्थन करता है।

  • निष्कर्ष यह है कि विज़ुअल सी ++ की मानक लाइब्रेरी को ठीक करने की आवश्यकता है, लेकिन उस निष्कर्ष को लेकर तर्क गलत है। इसके अलावा g ++ मानक लाइब्रेरी को ठीक करने की आवश्यकता है। G ++ संकलक का उल्लेख नहीं करना है।

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

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

यह सहायता कचरे में पड़ती है जब इसकी धारणाएं, जैसे विंडोज एएनएसआई संकीर्ण स्ट्रिंग अक्षर को एन्कोड किया जाता है, पकड़ नहीं लेता है।

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

वैसे, विंडोज़ में कंसोल में कोडपृष्ठ 65001 अभ्यास में प्रयोग योग्य नहीं है। कई कार्यक्रम बस दुर्घटनाग्रस्त हो जाते हैं। उदा। more


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

सी ++ धाराओं के साथ सही आउटपुट प्राप्त करना अधिक जटिल है।

यह इतना जटिल है कि इसका वर्णन करने के लिए कोई जगह नहीं है (सही ढंग से!), इसलिए मुझे इसके बारे में आपको इसके 2-भाग ब्लॉग आलेख श्रृंखला के बारे में संदर्भित करना होगा: part 1 और part 2

+0

समझ में आता है। लेकिन यह ओपी की समस्या को कैसे समझाता है कि प्रोग्राम _squares_ आउटपुट करता है? मैं यूटीएफ -8 बाइट्स के कंसोल का प्रतिनिधित्व करने की अपेक्षा करता हूं: रूसी एम (यू + 04 9 1) के लिए जो मेरी मशीन पर \ xD0 \ x99 या ''╗' होगी। –

+0

स्ट्रिंग यूटीएफ -8 है (चेक किया गया है, वास्तव में) मैं पूरी एमएसवीसी/यूटीएफ -8 अंक (बकवास) जानता हूं। मैं इसे सही तरीके से संभालने के बारे में जानता हूं (बीओएम के बिना मूल स्रोत यूटीएफ -8 का तो char * निश्चित रूप से सही यूटीएफ -8 प्राप्त करता है L "שלום" गड़बड़ हो गया है, लेकिन यह अलग कहानी है, मैं इसे "\ xXY" अक्षर के साथ भी कर सकता हूं , नतीजा वही है; धारणाओं के बारे में मूल मान्यताओं यह है कि 'std :: cout << str;' 'puts (str) 'के समान व्यवहार करना चाहिए। यह धारणा है और जीसीसी ने यह सही किया - कम से कम अनुमानित। अब मैं स्पष्ट रूप से समझते हैं कि 'std :: cout' कुछ कंसोल एपीआई का उपयोग करता है जो समस्या को और भी गंभीर बनाता है (टीबीसी ...) – Artyom

+2

क्योंकि यह वास्तव में कुछ अपेक्षित नहीं है। आखिर में मैंने आपका (भाग 2) आलेख पाया, यह http: // blogs.msdn.com/b/michkap/archive/2008/03/18/8306597.aspx कपलान का लेख और यह बग रिपोर्ट http://connect.microsoft.com/VisualStudio/feedback/details/431244/std-ostream-fails -to-write-utf-8-encoded-string-to-console। अंत में केवल एकमात्र उचित "समाधान" मेरा स्वयं का स्ट्रीम बफर बनाना है। टी पूरी तरह से क्रैपी विंडोज यूनिकोड मॉडल के बारे में उनका एक और उदाहरण है जब अनुप्रयोगों में से 1/2 यूनिकोड को अच्छी तरह से संभाल नहीं लेता है। – Artyom

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