2010-12-31 23 views
5

Trong kết quả này, tại sao tôi nhận được dòng mới bổ sung sau khi in các ký tự Unicode không phải ASCII?Perl Unicode glitch

Platform là Windows Vista và vấn đề xảy ra sau khi chcp 65001 nhưng không phải sau khi chcp 850

 
C:\>chcp 850 
Active code page: 850 

C:\>perl unicode_bug_1.pl 
Budweiser 
Budweiser 
Budweiser 
Bud─øjovick├¢ Budvar 
Bud─øjovick├¢ Budvar 
Bud─øjovick├¢ Budvar 

C:\>chcp 65001 
Active code page: 65001 

C:\>perl unicode_bug_1.pl 
Budweiser 
Budweiser 
Budweiser 
Budějovický Budvar 

Budějovický Budvar 

Budějovický Budvar 

từ chương trình này

#!perl 
use strict; 
use warnings; 

binmode (STDOUT, "encoding(UTF-8)"); # so no "Wide character in print" warning 

print "Budweiser\n" for 1..3; 
print "Bud\N{U+011B}jovick\N{U+00FD} Budvar\n" for 1..3; 
+2

Không có ý tưởng; không xảy ra cho tôi. Bạn có thể cho chúng tôi biết bất cứ điều gì về môi trường nơi bạn đang chạy này? – ysth

Trả lời

3

Điều này có vẻ là một lỗi trong Perl. Tôi đã nghĩ rằng đó là một lỗi trong trang mã Windows 65001 không thực sự được hỗ trợ cho giao diện điều khiển nhưng cuối cùng tôi đã thực hiện các chương trình thử nghiệm trong C và Perl và vấn đề không xảy ra trong phiên bản C. Nó xảy ra bất kể ký tự Unicode xuất hiện ở đâu trong dòng nhưng dòng bạn đang in phải rộng hơn bảng điều khiển hỗ trợ.

Đây là chương trình C của tôi:

#include "stdafx.h" 

#include "Windows.h" 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    BOOL b = SetConsoleOutputCP(65001); 
    printf("set console output codepage returned %d\n", b); 

    printf("cαfe\n"); 
    printf("1234567890 café\n"); 
    printf("1234567890 1234567890 cαfe\n"); 
    printf("1234567890 1234567890 1234567890 café\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 cαfe\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 1234567890 café\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n"); 
    printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n"); 

    return 0; 
}

Và đây là chương trình Perl của tôi:

# 

use utf8; 

binmode STDOUT, ':utf8'; 

printf STDOUT "cαfe\n"; 
printf STDOUT "1234567890 café\n"; 
printf STDOUT "1234567890 1234567890 cαfe\n"; 
printf STDOUT "1234567890 1234567890 1234567890 café\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 cαfe\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 café\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n"; 
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n";

CẬP NHẬT

Không, tôi đã sai, với sự giúp đỡ của một số các những người tại #perl trên irc.perl.org nó hóa ra lại là một lỗi trong Microsoft API. WriteFile được ghi lại để trả về số lượng byte được viết nhưng trả về số lượng ký tự được viết, phụ thuộc vào mã. A bug was filed in March 2010.

Có thêm thảo luận in the MSDN forums.

CẬP NHẬT 2

tôi đã đăng trên blog Michael Kaplan, "Sorting it all out", về vấn đề này và anh đáp lại bằng những bài viết tựa đề "Hidden in plain site: a purloined letter kind of a bug report". Anh ấy là một chuyên gia quốc tế hóa của Microsoft nên bạn chắc chắn sẽ tìm thấy một số thông tin chi tiết ở đó ...

0

tôi không nhận được bất kỳ dòng mới. Là dòng lệnh của bạn đủ rộng để phù hợp với đầu ra của bạn?

+0

Dòng lệnh của tôi đủ rộng nhưng tôi nhận thấy rằng vấn đề không xảy ra nếu tôi đặt trang mã thành 850 bằng cách sử dụng 'chcp 850' - tuy nhiên các ký tự không hiển thị đúng. Windows Vista 32 bit, Kích hoạt Perl 5.10.0 MSWin32-x86-đa luồng. – RedGrittyBrick

+0

đầu ra chcp tại đây: 932. Hãy thử điều đó, có thể? – Hugmeir

+0

@RedGrittyBrick, tôi không thấy vấn đề được mô tả trên Windows Vista 64 bit, Activestate Perl 5.10.1 MSWin32-x86-multi-thread. Có thể thử nâng cấp cài đặt Perl của bạn. –