हां, यह निराशाजनक है-कभी-कभी type
और अन्य प्रोग्राम प्रिंट गिबरिश, और कभी-कभी वे नहीं करते हैं।
सबसे पहले, यूनिकोड वर्ण केवल if the current console font contains the characters प्रदर्शित करेंगे। तो डिफ़ॉल्ट रास्टर फ़ॉन्ट के बजाय एक ट्रू टाइप फ़ॉन्ट जैसे लुसीडा कंसोल का उपयोग करें।
लेकिन यदि कंसोल फ़ॉन्ट में उस चरित्र को शामिल नहीं किया गया है जिसे आप प्रदर्शित करने का प्रयास कर रहे हैं, आपको अस्पष्टता के बजाय प्रश्न चिह्न दिखाई देंगे। जब आप gibberish प्राप्त करते हैं, बस फ़ॉन्ट सेटिंग्स की तुलना में अधिक चल रहा है।
कार्यक्रमों printf
जैसे मानक सी पुस्तकालय मैं/हे कार्यों का उपयोग करते हैं, कार्यक्रम के आउटपुट एन्कोडिंग कंसोल के आउटपुट एन्कोडिंग से मेल खाना चाहिए, या आप निरर्थक शब्द मिल जाएगा। chcp
वर्तमान कोड पेज दिखाता है और सेट करता है। मानक सी-लाइब्रेरी I/O फ़ंक्शंस का उपयोग करके सभी आउटपुट का मानना है कि यह कोडपृष्ठ chcp
द्वारा प्रदर्शित किया गया है।
कंसोल के आउटपुट एन्कोडिंग दो अलग अलग तरीकों से पूरा किया जा सकता है के साथ कार्यक्रम के आउटपुट एन्कोडिंग मिलान:
एक कार्यक्रम chcp
या GetConsoleOutputCP
का उपयोग कर सांत्वना की मौजूदा कोड पृष्ठ पर प्राप्त कर सकते हैं, और उत्पादन के लिए खुद को कॉन्फ़िगर में कि एन्कोडिंग, या
आप या एक कार्यक्रम से मिलान करने के chcp
या SetConsoleOutputCP
का उपयोग कर सांत्वना की मौजूदा कोड पृष्ठ पर सेट कर सकते हैं कार्यक्रम के डिफ़ॉल्ट आउटपुट एन्कोडिंग।
हालांकि, प्रोग्राम हैं जो Win32 API का उपयोग WriteConsoleW
साथ सांत्वना के लिए सीधे UTF-16LE तार लिख सकते हैं। कोडपेज सेट किए बिना सही आउटपुट प्राप्त करने का यही एकमात्र तरीका है। और उस फ़ंक्शन का उपयोग करते समय भी, यदि कोई स्ट्रिंग UTF-16LE एन्कोडिंग में शुरू करने के लिए नहीं है, तो Win32 प्रोग्राम को सही कोडपृष्ठ MultiByteToWideChar
पर पास करना होगा। इसके अलावा, WriteConsoleW
प्रोग्राम का आउटपुट रीडायरेक्ट होने पर काम नहीं करेगा; उस मामले में अधिक झुकाव की आवश्यकता है।
type
क्योंकि यह के लिए प्रत्येक फ़ाइल की शुरुआत की जाँच करता है एक UTF-16LE Byte Order Mark (BOM), अर्थात बाइट्स 0xFF 0xFE
समय की कुछ काम करता है। यदि यह चिह्न प्राप्त करता है, तो यह वर्तमान कोडपृष्ठ के बावजूद WriteConsoleW
का उपयोग कर फ़ाइल में यूनिकोड वर्ण प्रदर्शित करता है। लेकिन जब type
एक UTF-16LE बीओएम के बिना किसी भी फाइल ing, या किसी भी आदेश कि WriteConsoleW
फोन नहीं करता है के साथ गैर- ASCII वर्ण का उपयोग कर के लिए -आप सांत्वना कोडपेज और कार्यक्रम आउटपुट एन्कोडिंग एक दूसरे को मैच के लिए निर्धारित करने की आवश्यकता होगी।
हम इसे कैसे ढूंढ सकते हैं?
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
यहां विभिन्न यूनिकोड एनकोडिंग का एक समूह में परीक्षण फ़ाइल प्रिंट करने की एक जावा प्रोग्राम है:
यहाँ एक परीक्षण यूनिकोड वर्ण युक्त फ़ाइल है। यह किसी भी प्रोग्रामिंग भाषा में हो सकता है; यह केवल ASCII वर्ण या एन्कोडेड बाइट्स को stdout
पर प्रिंट करता है।
import java.io.*;
public class Foo {
private static final String BOM = "\ufeff";
private static final String TEST_STRING
= "ASCII abcde xyz\n"
+ "German äöü ÄÖÜ ß\n"
+ "Polish ąęźżńł\n"
+ "Russian абвгдеж эюя\n"
+ "CJK 你好\n";
public static void main(String[] args)
throws Exception
{
String[] encodings = new String[] {
"UTF-8", "UTF-16LE", "UTF-16BE", "UTF-32LE", "UTF-32BE" };
for (String encoding: encodings) {
System.out.println("== " + encoding);
for (boolean writeBom: new Boolean[] {false, true}) {
System.out.println(writeBom ? "= bom" : "= no bom");
String output = (writeBom ? BOM : "") + TEST_STRING;
byte[] bytes = output.getBytes(encoding);
System.out.write(bytes);
FileOutputStream out = new FileOutputStream("uc-test-"
+ encoding + (writeBom ? "-bom.txt" : "-nobom.txt"));
out.write(bytes);
out.close();
}
}
}
}
डिफ़ॉल्ट कोडपेज में आउटपुट? कुल कचरा!
Z:\andrew\projects\sx\1259084>chcp
Active code page: 850
Z:\andrew\projects\sx\1259084>java Foo
== UTF-8
= no bom
ASCII abcde xyz
German ├ñ├Â├╝ ├ä├û├£ ├ƒ
Polish ąęźżńł
Russian ð░ð▒ð▓ð│ð┤ðÁð ÐìÐÄÐÅ
CJK õ¢áÕÑ¢
= bom
´╗┐ASCII abcde xyz
German ├ñ├Â├╝ ├ä├û├£ ├ƒ
Polish ąęźżńł
Russian ð░ð▒ð▓ð│ð┤ðÁð ÐìÐÄÐÅ
CJK õ¢áÕÑ¢
== UTF-16LE
= no bom
A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ♣☺↓☺z☺|☺D☺B☺
R u s s i a n 0♦1♦2♦3♦4♦5♦6♦ M♦N♦O♦
C J K `O}Y
= bom
■A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ♣☺↓☺z☺|☺D☺B☺
R u s s i a n 0♦1♦2♦3♦4♦5♦6♦ M♦N♦O♦
C J K `O}Y
== UTF-16BE
= no bom
A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ☺♣☺↓☺z☺|☺D☺B
R u s s i a n ♦0♦1♦2♦3♦4♦5♦6 ♦M♦N♦O
C J K O`Y}
= bom
■ A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ☺♣☺↓☺z☺|☺D☺B
R u s s i a n ♦0♦1♦2♦3♦4♦5♦6 ♦M♦N♦O
C J K O`Y}
== UTF-32LE
= no bom
A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ♣☺ ↓☺ z☺ |☺ D☺ B☺
R u s s i a n 0♦ 1♦ 2♦ 3♦ 4♦ 5♦ 6♦ M♦ N
♦ O♦
C J K `O }Y
= bom
■ A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ♣☺ ↓☺ z☺ |☺ D☺ B☺
R u s s i a n 0♦ 1♦ 2♦ 3♦ 4♦ 5♦ 6♦ M♦ N
♦ O♦
C J K `O }Y
== UTF-32BE
= no bom
A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ☺♣ ☺↓ ☺z ☺| ☺D ☺B
R u s s i a n ♦0 ♦1 ♦2 ♦3 ♦4 ♦5 ♦6 ♦M ♦N
♦O
C J K O` Y}
= bom
■ A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ☺♣ ☺↓ ☺z ☺| ☺D ☺B
R u s s i a n ♦0 ♦1 ♦2 ♦3 ♦4 ♦5 ♦6 ♦M ♦N
♦O
C J K O` Y}
हालांकि, क्या हुआ अगर हम चाहते हैं कि बच गया फ़ाइलें type
? उनमें सटीक समान बाइट्स शामिल हैं जो कंसोल पर मुद्रित किए गए थे।
Z:\andrew\projects\sx\1259084>type *.txt
uc-test-UTF-16BE-bom.txt
■ A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ☺♣☺↓☺z☺|☺D☺B
R u s s i a n ♦0♦1♦2♦3♦4♦5♦6 ♦M♦N♦O
C J K O`Y}
uc-test-UTF-16BE-nobom.txt
A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ☺♣☺↓☺z☺|☺D☺B
R u s s i a n ♦0♦1♦2♦3♦4♦5♦6 ♦M♦N♦O
C J K O`Y}
uc-test-UTF-16LE-bom.txt
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
uc-test-UTF-16LE-nobom.txt
A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ♣☺↓☺z☺|☺D☺B☺
R u s s i a n 0♦1♦2♦3♦4♦5♦6♦ M♦N♦O♦
C J K `O}Y
uc-test-UTF-32BE-bom.txt
■ A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ☺♣ ☺↓ ☺z ☺| ☺D ☺B
R u s s i a n ♦0 ♦1 ♦2 ♦3 ♦4 ♦5 ♦6 ♦M ♦N
♦O
C J K O` Y}
uc-test-UTF-32BE-nobom.txt
A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ☺♣ ☺↓ ☺z ☺| ☺D ☺B
R u s s i a n ♦0 ♦1 ♦2 ♦3 ♦4 ♦5 ♦6 ♦M ♦N
♦O
C J K O` Y}
uc-test-UTF-32LE-bom.txt
A S C I I a b c d e x y z
G e r m a n ä ö ü Ä Ö Ü ß
P o l i s h ą ę ź ż ń ł
R u s s i a n а б в г д е ж э ю я
C J K 你 好
uc-test-UTF-32LE-nobom.txt
A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ♣☺ ↓☺ z☺ |☺ D☺ B☺
R u s s i a n 0♦ 1♦ 2♦ 3♦ 4♦ 5♦ 6♦ M♦ N
♦ O♦
C J K `O }Y
uc-test-UTF-8-bom.txt
´╗┐ASCII abcde xyz
German ├ñ├Â├╝ ├ä├û├£ ├ƒ
Polish ąęźżńł
Russian ð░ð▒ð▓ð│ð┤ðÁð ÐìÐÄÐÅ
CJK õ¢áÕÑ¢
uc-test-UTF-8-nobom.txt
ASCII abcde xyz
German ├ñ├Â├╝ ├ä├û├£ ├ƒ
Polish ąęźżńł
Russian ð░ð▒ð▓ð│ð┤ðÁð ÐìÐÄÐÅ
CJK õ¢áÕÑ¢
केवल बात यह है कि UTF-16LE फ़ाइल काम करता है, एक बीओएम, type
के माध्यम से कंसोल के लिए मुद्रित के साथ।
Z:\andrew\projects\sx\1259084>copy uc-test-UTF-16LE-bom.txt CON
■A S C I I a b c d e x y z
G e r m a n õ ÷ ³ ─ Í ▄ ▀
P o l i s h ♣☺↓☺z☺|☺D☺B☺
R u s s i a n 0♦1♦2♦3♦4♦5♦6♦ M♦N♦O♦
C J K `O}Y
1 file(s) copied.
तथ्य यह है कि copy CON
यूनिकोड सही ढंग से प्रदर्शित नहीं करता है से, हम निष्कर्ष निकाल सकते हैं type
आदेश पता लगाने के लिए तर्क है कि:
हम type
के अलावा और कुछ का उपयोग करते हैं फ़ाइल को मुद्रित करने के लिए, हम कचरा मिल पर एक यूटीएफ -16LE बीओएम फ़ाइल की शुरुआत, और प्रिंट करने के लिए विशेष विंडोज एपीआई का उपयोग करें।
हम जब यह एक फ़ाइल बाहर type
को जाता है एक डिबगर में cmd.exe
खोलकर देख सकते हैं:
type
के बाद एक फ़ाइल को खोलता है, यह 0xFEFF
यानी की एक बीओएम की जांच करता है, बाइट्स 0xFF 0xFE
छोटे-एंडियन में- और यदि ऐसा कोई बीओएम है, type
आंतरिक fOutputUnicode
ध्वज सेट करता है। तय करने के लिए WriteConsoleW
पर कॉल करने के लिए बाद में यह ध्वज चेक किया गया है।
लेकिन यह यूनिकोड आउटपुट के लिए type
प्राप्त करने का एकमात्र तरीका है, और केवल फ़ाइलों के लिए जो बीओएम हैं और यूटीएफ -16LE में हैं। अन्य सभी फ़ाइलों के लिए, और प्रोग्राम्स के लिए जिनके पास कंसोल आउटपुट को संभालने के लिए विशेष कोड नहीं है, आपकी फाइल वर्तमान कोडपृष्ठ के अनुसार व्याख्या की जाएगी, और संभवतः गिबर्निश के रूप में दिखाई देगी।
आप का अनुकरण कर सकते हैं कि type
कंसोल के लिए आउटपुट यूनिकोड अपने खुद के कार्यक्रमों में तो जैसे:
#include <stdio.h>
#define UNICODE
#include <windows.h>
static LPCSTR lpcsTest =
"ASCII abcde xyz\n"
"German äöü ÄÖÜ ß\n"
"Polish ąęźżńł\n"
"Russian абвгдеж эюя\n"
"CJK 你好\n";
int main() {
int n;
wchar_t buf[1024];
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
n = MultiByteToWideChar(CP_UTF8, 0,
lpcsTest, strlen(lpcsTest),
buf, sizeof(buf));
WriteConsole(hConsole, buf, n, &n, NULL);
return 0;
}
इस कार्यक्रम विंडोज डिफ़ॉल्ट कोड पृष्ठ पर उपयोग करते हुए कंसोल पर यूनिकोड मुद्रण के लिए काम करता है।
नमूना जावा प्रोग्राम के लिए, हम सही उत्पादन का एक छोटा सा द्वारा कोड पृष्ठ पर स्थापित करने के लिए मैन्युअल रूप से प्राप्त कर सकते हैं, हालांकि उत्पादन अजीब तरह से गड़बड़ हो जाता है ऊपर:
Z:\andrew\projects\sx\1259084>chcp 65001
Active code page: 65001
Z:\andrew\projects\sx\1259084>java Foo
== UTF-8
= no bom
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
ж эюя
CJK 你好
你好
好
�
= bom
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
еж эюя
CJK 你好
你好
好
�
== UTF-16LE
= no bom
A S C I I a b c d e x y z
…
हालांकि, एक सी कार्यक्रम है कि एक यूनिकोड UTF-8 कोडपेज सेट:
:
#include <stdio.h>
#include <windows.h>
int main() {
int c, n;
UINT oldCodePage;
char buf[1024];
oldCodePage = GetConsoleOutputCP();
if (!SetConsoleOutputCP(65001)) {
printf("error\n");
}
freopen("uc-test-UTF-8-nobom.txt", "rb", stdin);
n = fread(buf, sizeof(buf[0]), sizeof(buf), stdin);
fwrite(buf, sizeof(buf[0]), n, stdout);
SetConsoleOutputCP(oldCodePage);
return 0;
}
सही उत्पादन करता है
Z:\andrew\projects\sx\1259084>.\test
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
कहानी का नैतिक?
type
UTF-16LE फ़ाइलें WriteConsoleW
का उपयोग कर अपने वर्तमान कोडपेज की परवाह किए बिना एक बीओएम के साथ प्रिंट,
- Win32 कार्यक्रमों कंसोल के लिए उत्पादन यूनिकोड करने के लिए प्रोग्राम किया जा सकता है सकते हैं।
- अन्य कार्यक्रमों के लिए जो कोडपेज शायद अभी भी सेट और उसके अनुसार अपने आउटपुट एन्कोडिंग चीज़ों को एडजेस्ट कोड पृष्ठ पर था जब कार्यक्रम
- शुरू कर दिया और सब कुछ के लिए की परवाह किए बिना कंसोल पर यूनिकोड मुद्रित कर सकते हैं आप
chcp
के साथ चारों ओर गंदगी करना होगा, और होगा अजीब आउटपुट प्राप्त करें।
वाह, यह एसओ पर मैंने कभी देखा है सबसे विस्तृत जवाब होना चाहिए। Dissasembly प्रिंट और बहुभाषी कौशल के लिए अतिरिक्त क्रेडिट! बस सुंदर, महोदय! –
कोई भी Microsoft- विशिष्ट एक्सटेंशन _setmode (_fileno (stdout), _O_U16TEXT) का अध्ययन करना चाहता है जिसे VS2008 में पेश किया गया था। http://stackoverflow.com/a/9051543, और http://stackoverflow.com/a/12015918, और http://msdn.microsoft.com/en-us/library/tw4k6df8(v=vs देखें। 9 0) .aspx _setmode() और SetConsoleOutputCP() के बीच स्पष्ट पोर्टेबिलिटी अंतर के अलावा, अन्य दृष्टिकोणों में छिपी हुई अन्य सूक्ष्मताएं और दुष्प्रभाव भी हो सकते हैं जो पहली नज़र में पूरी तरह से समझ में नहीं आते हैं। यदि एंड्रयूडॉटन _setmode (fd, _O_U16TEXT) के बारे में किसी भी अवलोकन के साथ अपना उत्तर अपडेट कर सकता है, तो यह बहुत अच्छा होगा। – JasDev
हालांकि यह एक उत्कृष्ट उत्तर है, यह कहने में भ्रामक है कि कंसोल यूटीएफ -16 का समर्थन करता है। यह यूसीएस -2 तक ही सीमित है, यानि बुनियादी बहुभाषी विमान (बीएमपी) में पात्रों तक ही सीमित है। जब Win32 कंसोल सर्वर (conhost.exe, आजकल) लगभग 1 99 0 में डिज़ाइन किया गया था, यूनिकोड 16-बिट मानक था, इसलिए कंसोल स्क्रीन बफर प्रति 16-बिट WCHAR प्रति वर्ण सेल का उपयोग करता है। एक यूटीएफ -16 सरोगेट जोड़ी दो बॉक्स पात्रों के रूप में प्रिंट करता है। – eryksun