2010-06-28 10 views
6

मेरे कोड मूल रूप से यह है:सी ++: व्यापक वर्ण गलत तरीके से आउटपुट करते हैं?

wstring japan = L"日本"; 
wstring message = L"Welcome! Japan is "; 

message += japan; 

wprintf(message.c_str()); 

मैं विस्तृत तार उपयोग करने के इच्छुक रहा हूँ, लेकिन मैं नहीं जानता कि वे किस तरह outputted हैं, इसलिए मैंने wprintf इस्तेमाल किया। जब मैं इस तरह के रूप में कुछ चलाएँ:

./widestr | hexdump 

hexidecimal कोड पॉइंट्स इस बनाने के लिए:

65 57 63 6c 6d 6f 21 65 4a 20 70 61 6e 61 69 20 20 73 3f 3f 
e W c l m o ! e J  p a n a i  s ? ? 

क्यों वे सब क्रम में कूद रहे हैं? मेरा मतलब है कि अगर wprintf गलत है तो मुझे अभी भी यह नहीं मिलता है कि यह इस तरह के विशिष्ट जुआ आदेश में क्यों उत्पादन करेगा!

संपादित करें: अंतहीनता या कुछ? वे प्रत्येक दो अक्षर घुमाने लगते हैं। हुह।

संपादित 2: मैंने wcout का उपयोग करने का प्रयास किया, लेकिन यह सटीक हेक्साइडसिमल कोडपॉइंट्स को आउटपुट करता है। अजीब!

+0

शायद आपको 'cout << message << endl' आज़माएं। – phimuemue

+0

@phimuemue, यह काम नहीं करता है, यह मुझे लगभग 30 त्रुटियों को भेजता है, पहले 'widestr.cpp: 18: त्रुटि:' std :: cout << message 'में' ऑपरेटर << 'के लिए कोई मिलान नहीं है, जिसमें कई शामिल हैं ओस्ट्रीम चार लक्षण या कुछ, यह चौड़ी स्ट्रिंग आउटपुट नहीं करेगा! –

+1

आप किस प्लेटफ़ॉर्म और कंपाइलर का उपयोग कर रहे हैं? – hlovdal

उत्तर

11

आप अपेक्षा के अनुरूप स्थान को परिभाषित करने के

#include <stdio.h> 
    #include <string> 
    #include <locale> 
    #include <iostream> 

    using namespace std; 

    int main() 
    { 

      std::locale::global(std::locale("")); 
      wstring japan = L"日本"; 
      wstring message = L"Welcome! Japan is "; 

      message += japan; 

      wprintf(message.c_str()); 
      wcout << message << endl; 
    } 

निर्माण की जरूरत है (अर्थात विस्तृत स्ट्रिंग UTF-8 संकीर्ण और इसे प्रिंट में कनवर्ट करें)।

जब आप वैश्विक वातावरण को परिभाषित "" करने के लिए - आप सिस्टम स्थान सेट (और यह UTF-8 के रूप में बाहर मुद्रित किया जाएगा अगर यह UTF-8 है - यानी wstring परिवर्तित किया जाएगा)

संपादित करें: भूल जाओ मैंने sync_with_stdio के बारे में क्या कहा - यह सही नहीं है, वे डिफ़ॉल्ट रूप से सिंक्रनाइज़ होते हैं। जरूरत नहीं।

+1

आप इसे 'sync_with_stdio' और' wcout' जैसे ध्वनि बनाते हैं; वे पूरी तरह से अलग चीजें करते हैं। यदि आप सी ++ स्ट्रीम उपयोग ('wcout') के साथ सी स्ट्रीम फ़ंक्शंस (जैसे 'wprintf') को इंटरलीव करना चाहते हैं तो' sync_with_stdio' आवश्यक है; यदि आप 'wcout' द्वारा उपयोग किए गए लोकेल को बदलना चाहते हैं तो' imbue' की आवश्यकता है। –

+0

मैं इसका परीक्षण नहीं कर सकता, लेकिन 'wcout' को विंडोज़ पर कोडपेज सेटिंग्स के बिना काम करना चाहिए क्योंकि' wchar_t' विंडोज़ पर यूटीएफ -16 कोड इकाई है और यूटीएफ -16 विंडोज का एकमात्र देशी एन्कोडिंग है। तो 'std :: wcout' को किसी भी लोकेल रूपांतरण के बिना 'WriteConsoleW' का उपयोग करना चाहिए। यदि ऐसा नहीं होता है, तो यह एक लाइब्रेरी बग है। – Philipp

+2

@ फिलिप यह नहीं है कि यह मानक द्वारा कैसे परिभाषित किया जाता है। मानक कहता है कि स्थानीय अक्षरों के अनुसार विस्तृत वर्णों को संकीर्ण एन्कोडिंग में परिवर्तित किया जाना चाहिए। और यह वही किया जाता है। विंडोज के साथ मुद्दा यह है कि यह यूटीएफ -8 का समर्थन नहीं करता है। तो विंडोज़ के लिए आपको शायद 'लोकेल :: ग्लोबेल (लोकेल ("जापान")) का उपयोग करने की आवश्यकता है और यह आउटपुट में शिफ्ट-जेआईएस एन्कोडिंग का उपयोग करेगा। अन्यथा यह पात्रों को बदलने में विफल हो जाएगा। – Artyom

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