Java, không phải là không hợp lý, mã hóa các ký tự Unicode thành byte được mã hóa hệ thống gốc trước khi ghi chúng vào stdout
. Một số hệ điều hành, giống như nhiều bản phân phối Linux, sử dụng UTF-8
làm bộ ký tự mặc định của chúng, điều này rất hay.
Mọi thứ có một chút khác biệt trên Windows vì nhiều lý do tương thích ngược. Mã hóa hệ thống mặc định sẽ là một trong các mã "ANSI" và nếu bạn mở dấu nhắc lệnh mặc định (cmd.exe), nó sẽ là một trong các mã "DOS" OEM "cũ (mặc dù có thể nhận ANSI và Unicode tại đó with a bit of work).
Vì U + 0308 không nằm trong bất kỳ bộ ký tự "ANSI" nào (có thể là 1252 trong trường hợp của bạn), nó sẽ được mã hóa dưới dạng ký tự lỗi (thường là dấu chấm hỏi).
Một thay thế cho Unicode cho phép tất cả mọi thứ là để normalize chuỗi kết hợp U + 0069 U + 0308 đến ký tự đơn U + 00EF:
public static void emit(String foo) throws IOException {
System.out.println("Literal: " + foo);
System.out.print("Hex: ");
for (char ch : foo.toCharArray()) {
System.out.print(Integer.toHexString(ch & 0xFFFF) + " ");
}
System.out.println();
}
public static void main(String[] args) throws IOException {
String foo = "\u0069\u0308";
emit(foo);
foo = Normalizer.normalize(foo, Normalizer.Form.NFC);
emit(foo);
}
Dưới windows-1252
, mã này sẽ phát ra:
Literal: i?
Hex: 69 308
Literal: ï
Hex: ef
+1: Trên Ubuntu 9,04 trong thiết bị đầu cuối (gnome-terminal) đầu ra là i với diaresis như bạn có thể mong đợi nó. –
Tôi thích từ "diaeresis" này. Tôi có thể phải sử dụng nó thường xuyên hơn trong cuộc trò chuyện. – skaffman
:) cũng thử "umlaut", và bạn sẽ là người đàn ông của buổi tối. –