web-dev-qa-db-fra.com

Utilisation de 'use utf8;' me donne 'Caractère large imprimé'

Si je lance le programme Perl suivant:

Perl -e 'use utf8; print "鸡\n";'

Je reçois cet avertissement:

Wide character in print at -e line 1.

Si je lance ce programme Perl:

Perl -e 'print "鸡\n";'

Je ne reçois pas d'avertissement.

J'ai pensé use utf8 était nécessaire pour utiliser les caractères UTF-8 dans un script Perl. Pourquoi cela ne fonctionne pas et comment puis-je résoudre ce problème? J'utilise Perl 5.16.2. J'ai le même problème si cela est dans un fichier au lieu d'être une ligne sur la ligne de commande.

75
Eric Johnson

Sans pour autant use utf8 Perl interprète votre chaîne comme une séquence de caractères à un octet. Comme vous pouvez le constater, il y a quatre octets dans votre chaîne:

$ Perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10

Les trois premiers octets constituent votre personnage, le dernier est le saut de ligne.

L'appel à print envoie ces quatre caractères à STDOUT. Votre console détermine ensuite comment afficher ces caractères. Si votre console est configurée pour utiliser UTF8, elle interprétera ces trois octets comme votre seul caractère et c’est ce qui est affiché.

Si nous ajoutons dans le utf8 module, les choses sont différentes. Dans ce cas, Perl interprète votre chaîne comme deux caractères seulement.

$ Perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10

Par défaut, la couche de Perl IO suppose qu'elle fonctionne avec des caractères à un octet. Ainsi, lorsque vous essayez d'imprimer un caractère sur plusieurs octets, Perl pense que quelque chose ne va pas et vous avertit. Comme toujours, vous pouvez obtenir plus d'explications sur cette erreur en incluant use diagnostics. Il va dire ceci:

(Stupf8) Perl a rencontré un caractère large (> 255) alors qu'il ne s'y attendait pas. Cet avertissement est activé par défaut pour les E/S (comme print). Le moyen le plus simple de désactiver cet avertissement consiste simplement à ajouter la couche: utf8 à la sortie, par exemple. binmode STDOUT, ': utf8'. Une autre façon de désactiver l'avertissement consiste à ne pas ajouter d'avertissement 'utf8'; mais c'est souvent plus proche de la triche. En général, vous êtes censé marquer explicitement le descripteur de fichier avec un codage, voir open et perlfunc/binmode.

Comme d'autres l'ont souligné, vous devez dire à Perl d'accepter les sorties multi-octets. Il existe plusieurs façons de le faire (voir le Tutoriel Perl Unicode pour quelques exemples). L’un des moyens les plus simples est d’utiliser le -CS indicateur de ligne de commande - qui indique aux trois descripteurs de fichiers standard (STDIN, STDOUT et STDERR) de traiter UTF8.

$ Perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡

contre

$ Perl -Mutf8 -CS -e 'print "鸡\n";'
鸡

Unicode est un domaine vaste et complexe. Comme vous l'avez vu, de nombreux programmes simples semblent bien faire les choses, mais pour les mauvaises raisons. Lorsque vous commencez à réparer une partie du programme, la situation va souvent s'aggraver jusqu'à ce que vous ayez corrigé tout du programme.

102
Dave Cross

Tout use utf8; fait dire à Perl que le code source est encodé en UTF-8. Vous devez dire à Perl comment encoder votre texte:

use open ':std', ':encoding(UTF-8)';
69
ikegami

Encode toutes les sorties standard en UTF-8:

binmode STDOUT, ":utf8";
17
Boris Ivanov

Vous pouvez vous approcher de "juste faire utf8 partout" en utilisant le module CPAN utf8::all .

Perl -Mutf8::all -e 'print "鸡\n";'

Quand print reçoit quelque chose qu’il ne peut pas imprimer (caractère supérieur à 255 quand aucun :encoding couche est fourni), il suppose que vous vouliez l'encoder en utilisant UTF-8. Il le fait après avoir averti du problème.

12
Joel Berger

Vous pouvez utiliser ceci,

Perl -CS filename.

Cela mettra également fin à cette erreur.

5
Karthikeyan.R.S

En espagnol, vous pouvez trouver cette erreur en plus de commencer à utiliser:

use utf8;

Votre encodage d'éditeur est dans un encodage différent. Donc, ce que vous voyez dans l'éditeur n'est pas ce que Perl fait. Pour résoudre cette erreur, il suffit de modifier le codage de l'éditeur en nicode/UTF-8.

0
DiegoAr