2011-01-20 16 views
6

हे सब, मैंने केवल जावा सीखने का प्रयास करना शुरू कर दिया है और वास्तव में भ्रमित करने वाली किसी चीज में भाग लिया है!जावा यूनिकोड भ्रम

मैं जिस पुस्तक का उपयोग कर रहा हूं उससे एक उदाहरण टाइप कर रहा था। यह चार डेटा प्रकार का प्रदर्शन करना है।

public class CharDemo 
{ 
public static void main(String [] args) 
{ 
char a = 'A'; 
char b = (char) (a + 1); 
System.out.println(a + b); 
System.out.println("a + b is " + a + b); 
int x = 75; 
char y = (char) x; 
char half = '\u00AB'; 
System.out.println("y is " + y + " and half is " + half); 
} 
} 

सा है कि मुझे भ्रामक बयान, चार आधा = '\ u00ab' है:

कोड इस प्रकार है। पुस्तक बताती है कि \ u00AB प्रतीक '1/2' के लिए कोड है। जैसा कि वर्णन किया गया है, जब मैं cmd ​​से प्रोग्राम संकलित और चलाता हूं तो इस रेखा पर उत्पादित प्रतीक वास्तव में '1/2' है।

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

हर एक में मैंने पाया यह कहा गया है कि कोड/u00ab '1/2' के लिए नहीं था और इस के लिए वास्तव में था:

http://www.fileformat.info/info/unic...r/ab/index.htm तो क्या वर्ण सेट जावा उपयोग कर रहा है, मैंने सोचा था कि यूनिकोड चाहिए था बस इतना ही होना, यूनी, केवल एक। मैंने घंटों की खोज की है और कहीं भी मुझे एक चरित्र सेट नहीं मिल सकता है जो कहता है कि/u00AB 1/2 के बराबर है, फिर भी यह मेरा जावा कंपाइलर इसका अर्थ है।

मुझे यहां कुछ स्पष्ट याद आना चाहिए! किसी भी मदद के लिए धन्यवाद!

+3

मैं इस लेख में मदद करने के समस्या आप देख रहे हैं समझ में सलाह देते हैं: [निरपेक्ष न्यूनतम हर सॉफ्टवेयर डेवलपर बिल्कुल, सकारात्मक यूनिकोड और चरित्र सेट के बारे में पता होना चाहिए] (http://www.joelonsoftware.com/articles/Unicode.html) –

उत्तर

2

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

कक्षा नामों और परिवर्तनीय नामों में यूनिकोड वर्णों का उपयोग करके एक उदाहरण कोड है।

class 方 { 
    String 北 = "north"; 
    double π = 3.14159; 
} 

class UnicodeTest { 
    public static void main(String[] arg) { 
     方 x1 = new 方(); 
     System.out.println(x1.北); 
     System.out.println(x1.π); 
    } 
} 

जावा समय के आसपास बनाया गया था जब यूनिकोड मानक मूल्यों पात्रों में से एक बहुत छोटे सेट के लिए परिभाषित किया गया था। उसके बाद यह महसूस किया गया था कि 16-बिट्स उन सभी पात्रों को एन्कोड करने के लिए पर्याप्त होंगे जो कभी भी आवश्यक होंगे। इसके साथ में जावा को यूटीएफ -16 का उपयोग करने के लिए डिज़ाइन किया गया था। वास्तव में, चार डेटा प्रकार मूल रूप से 16-बिट यूनिकोड कोड बिंदु का प्रतिनिधित्व करने में सक्षम होने के लिए उपयोग किया जाता था।

यूटीएफ -8 वर्णसेट आरएफसी 2279 द्वारा निर्दिष्ट किया गया है;

UTF-16 वर्णसेट आरएफसी 2781

द्वारा निर्दिष्ट UTF-16 वर्णसेट सोलह-बिट मात्रा का उपयोग और इसलिए बाइट क्रम के प्रति संवेदनशील हैं। इन एन्कोडिंग में स्ट्रीम के बाइट ऑर्डर को यूनिकोड वर्ण '\ uFEFF' द्वारा दर्शाए गए प्रारंभिक बाइट-ऑर्डर चिह्न द्वारा इंगित किया जा सकता है। बाइट क्रम के अंक इस प्रकार नियंत्रित किया जाता है:

When decoding, the UTF-16BE and UTF-16LE charsets ignore byte-order marks; when encoding, they do not write byte-order marks. 

When decoding, the UTF-16 charset interprets a byte-order mark to indicate the byte order of the stream but defaults to big-endian if there is no byte-order mark; when encoding, it uses big-endian byte order and writes a big-endian byte-order mark. 

Also see this

+2

UTF-8 और UTF-16 ** नहीं ** वर्ण सेट कर रहे हैं; वे ** एक ही वर्णमाला के दो अलग चर-चौड़ाई एन्कोडिंग हैं: ** यूनिकोड। – tchrist

4

\u00ab चरित्र 1/2 चरित्र नहीं है, Unicode.org वेबसाइट से यह definitive code page देखें।

आप जो देख रहे हैं (मुझे लगता है कि) एक मंच जहां डिफ़ॉल्ट वर्ण एन्कोडिंग UTF-8 या लैटिन -1 नहीं है पर System.outPrintStream के उपयोग के परिणामस्वरूप। हो सकता है कि यह कुछ विंडोज वर्ण सेट है जैसा कि @ एक्स्टाव के उत्तर द्वारा सुझाया गया है? (यह भी कारण है कि \u00ab1/2 के रूप में प्रदर्शित किया जाता है की एक प्रशंसनीय विवरण ... और नहीं कुछ "सूचक" चरित्र है।)

(यूनिकोड और लैटिन -1, \00BD में 1/2 चरित्र के लिए कोडपॉइंट है।)

0

खैर, जब मुझे लगता है कि कोड का उपयोग मैं \u00BD के लिए < < के रूप में मैं चाहिए और 1/2 के रूप में यह होना चाहिए।

http://www.unicode.org/charts/

16

यह Windows प्लेटफार्मों पर एन्कोडिंग सांत्वना बेमेल के साथ एक अच्छी तरह से ज्ञात समस्या है।

जावा रनटाइम उम्मीद सिस्टम कंसोल द्वारा प्रयोग किया जाता है कि एन्कोडिंग प्रणाली डिफ़ॉल्ट एन्कोडिंग के समान है। हालांकि, विंडोज दो अलग-अलग एन्कोडिंग का उपयोग करता है: ANSI code page (system default encoding) and OEM code page (console encoding)

इसलिए, जब आप कंसोल के लिए यूनिकोड वर्ण U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK लिखने की कोशिश, जावा रनटाइम को उम्मीद है कि एन्कोडिंग सांत्वना एएनएसआई एन्कोडिंग (कि आपके मामले में Windows-1252 है), जहां यह यूनिकोड वर्ण 0xAB के रूप में प्रतिनिधित्व कर रहा है। हालांकि, वास्तविक एन्कोडिंग सांत्वना जहां 0xAB मतलब है , OEM एन्कोडिंग (आपके मामले में CP437) है।

इसलिए System.out.println() के साथ विंडोज कंसोल के लिए डेटा मुद्रण गलत परिणाम पैदा करता है।

सही परिणाम आप के बजाय System.console().writer().println() उपयोग कर सकते हैं पाने के लिए।

+0

धन्यवाद, यह समझ में आता है, लेकिन आप उल्लेख करते हैं कि विंडोज कंसोल में प्रिंटिंग डेटा गलत परिणाम उत्पन्न करता है। यह उदाहरण सीधे जावा पुस्तक से था, लेखक को पता था कि एबी आधा होगा। क्या यह सिर्फ खराब लेखन है कि उसने यह समझाया नहीं? – Nick

+1

@ निक: फिर यह एक खराब लेखन है। शायद लेखक शायद ही कभी गैर-हम-एसीआई अक्षरों के साथ काम करते थे और इसलिए इस समस्या से अपरिचित थे। – axtavt

+1

+1। यह वास्तव में मूर्खतापूर्ण है। जावा और विंडोज दोनों यूटीएफ -16LE के रूप में मेमोरी में एन्कोडेड देशी-यूनिकोड स्ट्रिंग का उपयोग करते हैं। और फिर भी वे बाइट्स के माध्यम से एक चरित्र-मैंगलिंग एन्कोड-डीकोड चक्र के बिना बिना किसी दूसरे से बात करने में असमर्थ रहते हैं। – bobince

3

0xAB अच्छे पुराने Codepage 437 है, जो है क्या विंडोज टर्मिनलों डिफ़ॉल्ट, no matter what codepage you actually set द्वारा उपयोग करेगा में 1/2 है।

तो, वास्तव में, char मान जावा प्रोग्राम में "« "वर्ण का प्रतिनिधित्व करता है, और यदि आप उस char को जीयूआई में प्रस्तुत करते हैं या इसे एक सैन ऑपरेटिंग सिस्टम पर चलाते हैं, तो आपको वह चरित्र मिल जाएगा। तुम भी Windows में उचित उत्पादन को देखने के लिए, "रेखापुंज फ़ॉन्ट्स" से दूर सीएमडी में अपने फ़ॉन्ट सेटिंग्स स्विच चाहते हैं (क्लिक करें ऊपरी-बाएं आइकन, गुण, फ़ॉन्ट टैब)। उदाहरण के लिए, ल्युसिडा कंसोल के साथ, मैं यह कर सकता:

C:\Users\Documents>java CharDemo 
131 
a + b is AB 
y is K and half is ½  

C:\Users\Documents>chcp 1252 
Active code page: 1252 

C:\Users\Documents>java CharDemo 
131 
a + b is AB 
y is K and half is « 

C:\Users\Documents>chcp 437 
Active code page: 437 
+2

ओह, और यदि आप कभी उससे मिलते हैं तो उसके साथ अपने पुस्तक के लेखक को हराएं। – themel

+0

एक अलग पुस्तक पर जाने के लिए कोई सिफारिशें? यह बिल्कुल शुरुआत में शुरू करना है, हालांकि, मूल बातें और बुनियादी बातों और ऊपर। – Nick

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