2010-12-31 17 views
5

W tym wyjściu, dlaczego otrzymuję dodatkowe znaki nowej linii po wydrukowaniu znaków Unicode w formacie innym niż ASCII?Perl Unicode glitch

Platforma Windows Vista i problem występuje po chcp 65001 ale nie po 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 

z tego programu

#!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

Brak pomysłu; nie dzieje się dla mnie. Czy możesz nam powiedzieć coś o środowisku, w którym to uruchamiasz? – ysth

Odpowiedz

3

Wygląda na to, że jest to błąd w Perlu. Myślałem, że to błąd na stronie kodowej Windows 65001, który nie jest obsługiwany przez konsolę, ale w końcu zrobiłem programy testowe w C i Perlu, a problem nie występuje w wersji C. Dzieje się tak bez względu na to, gdzie w linii występuje znak Unicode, ale linia, którą drukujesz, musi być szersza niż obsługuje konsola.

Oto mój program w C:

#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; 
}

I tu jest mój program Perl:

# 

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";

UPDATE

Nie myliłem się, z pomocą niektórych faceci na #perl na irc.perl.org to okazuje się być błędem w API Microsoftu. WriteFile jest udokumentowany, aby zwrócić liczbę zapisanych bajtów, ale zwraca liczbę znaków zapisanych, która zależy od strony kodowej. A bug was filed in March 2010.

Istnieje więcej dyskusji in the MSDN forums.

UPDATE 2

napisałem blogu Michael Kaplan, w "Sorting it all out", o tym problemie, a on odpowiedział z artykułu zatytułowanego "Hidden in plain site: a purloined letter kind of a bug report". Jest ekspertem od internacjonalizacji firmy Microsoft, więc na pewno znajdziesz tam pewne spostrzeżenia ...

0

ja nie dostaję żadnych nowych linii. Czy linia poleceń jest wystarczająco szeroka, aby dopasować ją do wyników?

+0

Moja linia poleceń jest wystarczająco szeroka, ale zauważyłem, że problem nie występuje, jeśli ustawię stronę kodową na 850 przy użyciu 'chcp 850' - jednak wtedy wszystkie znaki nie będą poprawnie wyświetlane. Windows Vista 32-bitowy, Activestate Perl 5.10.0 MSWin32-x86-multi-thread. – RedGrittyBrick

+0

Tutaj można uzyskać wynik: 932. Spróbuj? – Hugmeir

+0

@RedGrittyBrick, Nie widzę opisanego problemu w systemie Windows Vista w wersji 64-bitowej, Activestate Perl 5.10.1 MSWin32-x86-multi-thread. Może spróbuj uaktualnić instalację Perla. –