免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 43232 | 回复: 36
打印 上一主题 下一主题

Windows中文 - 编码!编码!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-02-18 13:40 |只看该作者 |倒序浏览
本帖最后由 兰花仙子 于 2011-08-25 13:26 编辑

同学们近期编码问题很多,稍微总结下。

Windows的终端环境是GBK吧,读取UTF-8的编码,自然会乱码。

比如文件abc.txt是UTF-8格式的,那么如何读取它呢?

第0种方式(推荐):
  1. use encoding "utf8", STDOUT => 'gbk';
  2. open HD,"<:encoding(UTF-8)","data.txt" or die $!;
  3. while(<HD>) {
  4.         print;
  5. }
复制代码
use encoding "utf8"表明程序的缓冲、变量环境是UTF-8,STDOUT=>'gbk'表示输出环境为GBK。
open HD,"<:encoding(UTF-8)","data.txt"表明打开和转换UTF-8文件。


第1种方式:
  1. use Encode;

  2. open HD,"<:encoding(UTF-8)","abc.txt" or die $!;
  3. while(<HD>) {
  4.         print encode("gb2312",$_);
  5. }
复制代码
如上代码,<:encoding(UTF-8)表明在open时,已识别并转换了读入文件的UTF-8编码。
然后print encode("gb2312",$_)将内容用gb2312编码输出,这样就正确显示了。


第2种方式:
  1. use Encode;

  2. open HD,"abc.txt" or die $!;
  3. while(<HD>) {
  4.         print encode("gb2312",decode("utf8",$_));
  5. }
复制代码
用普通的open打开文件,然后对文件的每一行,先用decode将内容转换成perl内部的编码格式(它的作用相当于open with "<:encoding(UTF-8)")。
然后,再调用encode将转换后的内容,以gb2312编码进行输出,这样也显示正常。


其他方式还有本版一位大侠推荐的
  1. use open ':encoding(GBK)', ':std';
  2. use open ':encoding(UTF-8)';
  3. open HD,"data.txt";
复制代码
不多述。

论坛徽章:
0
2 [报告]
发表于 2011-02-18 18:47 |只看该作者
回复 1# 兰花仙子


    推销一下水木社区上我的一个帖子:)

Perl实用中文处理步骤
http://www.newsmth.net/bbscon.ph ... =57467&ftype=11

用encode是字符串级别的处理编码问题,上面这个帖子是I/O级别的实用总结

欢迎仙子来水木社区Perl版指导工作,这里的flw应该就是水木的flw吧:)

论坛徽章:
0
3 [报告]
发表于 2011-02-18 20:29 |只看该作者
好帖,好文,好斑竹。

论坛徽章:
0
4 [报告]
发表于 2011-02-18 21:57 |只看该作者
2、脚本开头加上:
  use utf8;
  use open ":encoding(gbk)", ":std";
  意思是脚本里的字符串都用utf8处理,但是标准输入输出用gbk(默认的代码页编码)
  做到这一步,脚本里就可以直接用中文了,字符串、正则表达式都没问题


看了你的帖子,不错。

use open ":encoding(gbk)", ":std";

是否换成:

use encoding ":gbk";

效果一样?

因为:

1. use utf8 只是告诉编译器,脚本用utf8写的,除此之外无任何意义。
2. use encoding ":gbk" 告诉编译器,输入输出,字串,<DATA>都是GBK编码。

论坛徽章:
0
5 [报告]
发表于 2011-02-18 22:32 |只看该作者
回复 4# 兰花仙子


        use open比use encoding的方式好,至少use encoding不能作用于STDERR,而use open无此问题
    要把encoding默认设为gbk,觉得不如设为utf8好,这样文件也存为utf-8编码,
   
http://www.newsmth.net/bbscon.php?bid=226&id=57480
以及后续的深入讨论http://www.newsmth.net/bbstcon.p ... 458&start=57480

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2011-02-18 22:52 |只看该作者
牛人终于登录 ChinaUnix 了。

论坛徽章:
0
7 [报告]
发表于 2011-02-19 10:14 |只看该作者
use encoding ":gbk";

这个怎么报语法错误,是不是use open  ':encoding(GBK)';

论坛徽章:
0
8 [报告]
发表于 2011-02-19 10:32 |只看该作者
use utf8;是标识程序的编码

use open IO  => ":encoding(gbk)"; 这个IO是指输入与输出的编码吗?
我看这样只能处理输入用gbk,输出还是不起作用

要用
  1. use open IO  => ":encoding(gbk)";
  2. use open ':std';
复制代码
这样才管用

论坛徽章:
0
9 [报告]
发表于 2011-02-19 10:42 |只看该作者
回复  兰花仙子


        use open比use encoding的方式好,至少use encoding不能作用于STDERR,而use ...
FenRagwort 发表于 2011-02-18 22:32



    thanks!

可以这样分别设置stdio流和其它IO流的编码:

use open ':encoding(GBK)', ':std';
use open ':encoding(UTF-';

这样stdio将使用GBK编码,其它文件IO将默认使用UTF-8


这个印象深刻,学习了!

论坛徽章:
0
10 [报告]
发表于 2011-02-19 16:20 |只看该作者
本帖最后由 yakczh 于 2011-02-19 16:23 编辑

use encoding  "xxx" 可以解决页面编码的问题
use open ":encoding(xxx)";   可以解决从外部文件io的编码问题
但是命令参数 $ARGV  不加上面任一个encoding正常,一旦加上了以后就有问题了
比如 终端是utf8环境,读gbk文件,程序用utf8编码保存

  1. use encoding "utf8";#,STDIN => "utf8",STDOUT => "utf8";
  2. use open ':std';
  3. use open IO  => ":encoding(gbk)";

  4. sub getbytes{
  5.         my  @bytes=unpack("C*",shift);
  6.         map {$_=sprintf("%4x",$_)} @bytes;
  7.         return  join "\t",@bytes;
  8.         
  9. }

  10. sub debug {
  11. my $str=shift;
  12. print "\n string:", $str;
  13. print "\n bytes :",getbytes($str);


  14. }
  15. $stdin= $ARGV[0];
  16. print "\n ---------- stdin-----------\n";
  17. debug($stdin);
  18. $inline="中文abc";
  19. print "\n --------- page encode ------\n";
  20. debug($inline);
  21. my $filename="gbk.txt";
  22. my $text='';
  23. open FH,$filename;
  24. do {local $/,$text=<FH>;};
  25. close FH;
  26. print "\n ---------- io --------------\n";
  27. debug($text);
复制代码
运行 perl  test.pl  中文

或者在gbk环境下读utf8文件,文件用gbk编码保存

  1. use encoding "gbk";#,STDIN => "utf8",STDOUT => "utf8";
  2. use open ':std';
  3. use open IO  => ":encoding(utf8)";

  4. sub getbytes{
  5.         my  @bytes=unpack("C*",shift);
  6.         map {$_=sprintf("%4x",$_)} @bytes;
  7.         return  join "\t",@bytes;
  8.         
  9. }

  10. sub debug {
  11. my $str=shift;
  12. print "\n string:", $str;
  13. print "\n bytes :",getbytes($str);


  14. }
  15. $stdin= $ARGV[0];
  16. print "\n ---------- stdin-----------\n";
  17. debug($stdin);
  18. $inline="中文abc";
  19. print "\n --------- page encode ------\n";
  20. debug($inline);
  21. my $filename="u8.txt";
  22. my $text='';
  23. open FH,$filename;
  24. do {local $/,$text=<FH>;};
  25. close FH;
  26. print "\n ---------- io --------------\n";
  27. debug($text);
复制代码
运行 perl  test.pl  中文 
内部编码和外部io都没有问题,但是命令参数编码始终不对
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP