2013-06-05 11 views
7

मुझे iostream का उपयोग कर लिनक्स टर्मिनल पर कुछ यूनिकोड वर्ण मुद्रित करने की आवश्यकता है। हालांकि अजीब चीजें होती हैं। जब मैं लिख:सी ++ यूनिकोड वर्ण मुद्रण

cout << "\u2780"; 

मैं: है, जो लगभग ठीक है कि मैं क्या चाहता हूँ। लेकिन अगर मैं लिखने:

cout << '\u2780'; 

मैं: 14851712

समस्या यह है कि, मुझे संकलन समय पर मुद्रित सटीक चरित्र नहीं पता है। इसलिए मैं कुछ ऐसा करना चाहता हूं:

int x; 
// some calculations... 
cout << (char)('\u2780' + x); 

कौन सा प्रिंट: wcout या wchar_t का उपयोग करके या तो काम न करें। मैं सही प्रिंटिंग कैसे प्राप्त करूं?

जो मैंने इंटरनेट पर पाया, उससे मुझे लगता है कि मैं सीधे डेबियन व्हीजी भंडार से जी ++ 4.7.2 कंपाइलर का उपयोग करता हूं।

+0

ऑपरेटर 'L' साथ wchar_t उपयोग कर रहे हैं? यदि संभव हो तो अपना पूरा कोड पोस्ट करें या [sscce.org] (SSCCE) – pinkpanther

+0

यदि आप यूनिकोड एन्कोडिंग के साथ गड़बड़ नहीं करना चाहते हैं, तो आप इसे जोड़ने के बजाय 'x' के संभावित मानों पर तारों को मैप करने के लिए एक तालिका का उपयोग कर सकते हैं। – dyp

+0

की संभावित डुप्लिकेट [C++ में यूनिकोड वर्ण मुद्रित करने के लिए कैसे?] (Http://stackoverflow.com/questions/12015571/how-to-print-unicode-character-in-c) –

उत्तर

6

यूनिकोड चरित्र \u2780char डेटाटाइप के लिए सीमा के बाहर है। आप इस संकलक चेतावनी इसके बारे में बताने के लिए प्राप्त हो जाना चाहिए: (कम से कम मेरे जी ++ 4.7.3 यह देता है)

test.cpp:6:13: warning: multi-character character constant [-Wmultichar] 

आप U + 2780 की तरह पात्रों के साथ काम करना चाहते हैं, तो आप करना होगा एकल इकाइयों के रूप में विस्तृतचर डेटाटाइप wchar_t का उपयोग करें, या यदि आप भाग्यशाली हैं तो सी ++ 11, char32_t या char16_t के साथ काम करने में सक्षम होने के लिए पर्याप्त भाग्यशाली हैं। ध्यान दें कि एक 16-बिट इकाई यूनिकोड वर्णों की पूरी श्रृंखला का प्रतिनिधित्व करने के लिए पर्याप्त नहीं है।

यदि यह आपके लिए काम नहीं कर रहा है, तो संभव है क्योंकि डिफ़ॉल्ट "सी" लोकेल में गैर-ASCII आउटपुट के लिए समर्थन नहीं है। उस समस्या को ठीक करने के लिए आप प्रोग्राम की शुरुआत में setlocale पर कॉल कर सकते हैं; कि जिस तरह से आप कर सकते हैं उत्पादन पात्रों की पूरी रेंज उपयोगकर्ता किसी भी स्थान के द्वारा समर्थित: (जो या वर्ण आप उपयोग के सभी के लिए समर्थन नहीं हो सकता है)

#include <clocale> 
#include <iostream> 

using namespace std; 

int main() { 
    setlocale(LC_ALL, ""); 
    wcout << L'\u2780'; 
    return 0; 
} 
+0

निश्चित रूप से एक ही समस्या हो सकता है कौन सा अन्य अक्षर (एसएमपी) अगर आकार (wchar_t) <4'। मैं 'char16_t' या' char32_t' btw का उपयोग करने का सुझाव दूंगा। – dyp

+2

अतिरिक्त एन्कोडिंग उपसर्ग 'L' लिए, वहाँ' 'है UTF8' एन्कोडिंग के लिए u8',' 'char16_t' के लिए u', और' 'char32_t' के लिए U'। – Appleshell

+0

लोकल नाम के लिए '' "पास करते समय' setlocale' उपयोगकर्ता के पसंदीदा लोकेल को सेट करता है, जो कि एक यूनिकोड लोकेल नहीं है। – dyp

4

जब आप लिखना

cout << "\u2780"; 

कंपाइलर निष्पादन चरित्र सेट में उस वर्ण के उचित एन्कोडिंग में \ u2780 परिवर्तित करता है। शायद यह यूटीएफ -8 है, और इसलिए स्ट्रिंग चार बाइट्स (चरित्र के लिए तीन, शून्य टर्मिनेटर के लिए) होने के समाप्त होती है।

यदि आप रन टाइम पर चरित्र उत्पन्न करना चाहते हैं तो आपको रनटाइम पर यूटीएफ -8 में समान रूपांतरण करने की आवश्यकता है कि संकलक संकलन समय पर कर रहा है।


सी ++ 11, एक आसान wstring_convert टेम्पलेट और codecvt पहलुओं कि यह कर सकते हैं प्रदान करता है तथापि libstdC++, मानक पुस्तकालय कार्यान्वयन कि जीसीसी के साथ आता है, फिर भी चारों ओर उन्हें (जीसीसी 4.8 के रूप में) को लागू करने के लिए मिल गया नहीं किया गया है । निम्नलिखित दिखाता है कि इन सुविधाओं का उपयोग कैसे करें, लेकिन आपको या तो एक अलग मानक लाइब्रेरी कार्यान्वयन का उपयोग करना होगा या उन्हें लागू करने के लिए libstdC++ का इंतजार करना होगा।

#include <codecvt> 

int main() { 
    char32_t base = U'\u2780'; 

    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert; 
    std::cout << convert.to_bytes(base + 5) << '\n'; 
} 

आप यूटीएफ -8 के उत्पादन के किसी अन्य तरीके का भी उपयोग कर सकते हैं।उदाहरण के लिए, आइकन-आईसीयू, और पूर्व-सी ++ 11 codecvt_byname पहलुओं का मैन्युअल उपयोग सभी काम करेंगे। (मैं इनमें से उदाहरणों से पता चलता नहीं है क्योंकि कि कोड wstring_convert द्वारा अनुमति दी सरल कोड की तुलना में अधिक शामिल किया जाएगा।)


एक वैकल्पिक कि पात्रों की एक छोटी संख्या के लिए काम करेंगे की एक सरणी बनाने के लिए किया जाएगा अक्षर का उपयोग कर तार।

char const *special_character[] = { "\u2780", "\u2781", "\u2782", 
    "\u2783", "\u2784", "\u2785", "\u2786", "\u2787", "\u2788", "\u2789" }; 

std::cout << special_character[i] << '\n'; 
0

कार्यक्रम की वजह से एक पूर्णांक प्रिंट सी ++ 11 §2.14.3/1:

एक multicharacter शाब्दिक, या एक साधारण चरित्र शाब्दिक वाली एकल सी चार में प्रदर्शनीय नहीं निष्पादन चरित्र सेट, सशर्त रूप से समर्थित है, प्रकार int है, और एक कार्यान्वयन-परिभाषित मान है।

निष्पादन चरित्र सेट char प्रतिनिधित्व कर सकता है, यानी ASCII।

आप मिल गया क्या 14,851,712 है, या हेक्साडेसिमल e29e80, जो U + 2780 के लिए UTF-8 प्रतिनिधित्व है में। int में यूटीएफ -8, एक मल्टीबाइट एन्कोडिंग डालने से पागल और बेवकूफ है, लेकिन यह आपको "सशर्त रूप से समर्थित, कार्यान्वयन-परिभाषित" सुविधा से मिलता है।

एक UTF-32 मूल्य पाने के लिए, U'\u2780' का उपयोग करें। पहले Uchar32_t प्रकार और यूटीएफ -32 एन्कोडिंग निर्दिष्ट करता है (यानी 31 बिट्स तक लेकिन कोई सरोगेट जोड़े नहीं)। दूसरा \u एक सार्वभौमिक-वर्ण-नाम निर्दिष्ट करता है जिसमें कोड बिंदु होता है। wcout के साथ अनुमानित रूप से संगत मान प्राप्त करने के लिए, L'\u2780' का उपयोग करें, लेकिन यह आवश्यक नहीं है कि यूनिकोड रनटाइम मान का उपयोग न करें और न ही आपको दो से अधिक बाइट स्टोरेज प्राप्त करें।

मज़बूती से जोड़ तोड़ और यूनिकोड कोडपॉइंट मुद्रण, के रूप में अन्य उत्तर उल्लेख किया है, सी ++ मानक अभी तक वहाँ मिल नहीं किया गया है का सवाल है। जॉनी का जवाब सबसे अच्छा तरीका है, फिर भी यह मानता है कि संकलक और उपयोगकर्ता का वातावरण एक ही लोकेल का उपयोग कर रहा है, जो अक्सर सत्य नहीं होता है।

आप u8"\u2780" का उपयोग कर स्रोत में यूटीएफ -8 तारों को भी निर्दिष्ट कर सकते हैं और std::locale::global(std::locale("en_US.UTF-8")); जैसे कुछ का उपयोग कर रनटाइम पर्यावरण को UTF-8 पर बल दे सकते हैं। लेकिन अभी भी किसी न किसी किनारों है। जोनी सी ++ इंटरफ़ेस std::locale::global<locale> से है, जो सी ++ इंटरफ़ेस करने के लिए एक समाधान के ओएस एक्स और शायद अन्य प्लेटफार्मों पर जीसीसी में तोड़ा जा रहा है के बजाय <clocale> से सी इंटरफ़ेस std::setlocale का उपयोग कर पता चलता है। मुद्दे प्लेटफॉर्म-संवेदनशील हैं कि आपके लिनक्स डिस्ट्रो ने अपने स्वयं के जीसीसी पैकेज में पैच लगाया होगा।

+0

या तो आप या शायद मुझे कुछ याद आया, क्योंकि कंपाइलर अब आग्रह करता है कि "यू को दायरे में घोषित नहीं किया गया था"। – Sventimir

+0

@Sventimir स्पष्ट रूप से यह जीसीसी 4.7.2 में समर्थित नहीं है, लेकिन यह सी ++ 11 मानक का हिस्सा है। बस 'एल' xxx 'के साथ जाओ; लिनक्स में यह अनिवार्य रूप से वही काम करना चाहिए। – Potatoswatter

+0

'gcc --std = C++ 11' कॉल के साथ C++ 11 समर्थन जोड़ना या तो काम नहीं करता है। यह अब संकलित करता है, लेकिन चार (10112) के दशमलव मान को प्रिंट करता है, न कि चार स्वयं। – Sventimir

0

लिनक्स में, मैं सबसे अनुभवहीन तरह से रूप में किसी भी यूनिकोड को प्रिंट सफल रहे हैं सीधे:

std::cout << "ΐ , Α, Β, Γ, Δ, ,Θ , Λ, Ξ, ... ±, ... etc" 
संबंधित मुद्दे