首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用'use utf8;‘给我’打印中的宽字符‘

使用'use utf8;‘给我’打印中的宽字符‘
EN

Stack Overflow用户
提问于 2013-03-05 04:29:51
回答 6查看 69.9K关注 0票数 90

如果我运行下面的Perl程序:

代码语言:javascript
复制
perl -e 'use utf8; print "鸡\n";'

我得到这样的警告:

代码语言:javascript
复制
Wide character in print at -e line 1.

如果我运行这个Perl程序:

代码语言:javascript
复制
perl -e 'print "鸡\n";'

我没有收到任何警告。

我认为use utf8需要在Perl脚本中使用UTF-8字符。为什么这不起作用,我该如何修复它?我使用的是Perl 5.16.2。如果这是一个文件,而不是命令行上的一行程序,我也会遇到同样的问题。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-03-05 18:56:28

如果没有use utf8,Perl会将字符串解释为单字节字符序列。您的字符串中有四个字节,您可以从下面看到:

代码语言:javascript
复制
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10

前三个字节组成字符,最后一个字节是换行符。

print的调用将这四个字符发送到STDOUT。然后,您的控制台会计算出如何显示这些字符。如果您的控制台设置为使用UTF8,那么它会将这三个字节解释为您的单个字符,这就是所显示的内容。

如果我们添加utf8模块,情况就不同了。在本例中,Perl仅将字符串解释为两个字符。

代码语言:javascript
复制
$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10

默认情况下,Perl的IO层假定它使用单字节字符。因此,当您尝试打印多字节字符时,Perl会认为有问题并给出警告。一如既往,您可以通过包含use diagnostics来获得有关此错误的更多解释。它会这样说:

(S utf8) Perl遇到一个宽字符(>255),而它不需要宽字符。默认情况下,对于I/O (如打印),此警告处于打开状态。消除此警告的最简单方法是在输出中添加:utf8层,例如binmode STDOUT,':utf8‘。另一种关闭警告的方法是不添加警告“UTF8”;但这通常更接近于作弊。通常,您应该显式地使用编码标记文件句柄,请参阅open和perlfunc/binmode。

正如其他人所指出的,您需要告诉Perl接受多字节输出。有很多方法可以做到这一点(有关示例,请参阅Perl Unicode Tutorial )。最简单的方法之一是使用-CS命令行标志-它告诉三个标准文件句柄(STDIN、STDOUT和STDERR)来处理UTF8。

代码语言:javascript
复制
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡

vs

代码语言:javascript
复制
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡

Unicode是一个大而复杂的领域。正如您所看到的,许多简单的程序似乎做了正确的事情,但原因是错误的。当你开始修复程序的一部分时,情况通常会变得更糟,直到你修复了所有的程序。

票数 112
EN

Stack Overflow用户

发布于 2013-03-05 04:34:09

use utf8;所要做的就是告诉Perl源代码是使用UTF-8编码的。您需要告诉Perl如何对文本进行编码:

代码语言:javascript
复制
use open ':std', ':encoding(UTF-8)';
票数 82
EN

Stack Overflow用户

发布于 2014-02-18 05:18:34

将所有标准输出编码为UTF-8:

代码语言:javascript
复制
binmode STDOUT, ":utf8";
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15210532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档