A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郭亚飞 黑马帝   /  2011-9-5 21:08  /  2188 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

[code=java]import java.io.*;
public class review
{
    public static void main(String []args)throws Exception
     {
          System.out.println("please enter some chatacters:");
          InputStreamReader isr=new InputStreamReader(System.in,"gb2312");
          //InputStreamReader isr=new InputStreamReader(System.in,"iso8859-1");
          BufferedReader br=new BufferedReader(isr);
          String strLine=br.readLine();
          for(int i=0;i<strLine.length();i++)
            {
                System.out.println(Integer.toHexString(strLine.charAt(i)));
            }
          isr.close();
          System.out.println(strLine);
     }   
}
InputStreamReader isr=new InputStreamReader(System.in,"gb2312");
//InputStreamReader isr=new InputStreamReader(System.in,"iso8859-1");[/code]输入“中国”
当用gb2312编码时,打出的是unicode码,最后中国能正常打印!
当用iso8859-1编码时,打出的是gb2312码,最后中国不能正常打印!
请问这是为什么啊?到底什么情况打印unicode码什么情况打印本地字符集的编码啊?
各种编码,各种转换,各种混淆,各种迷糊...求关注,求详解,有木有!有木有!!!:'(

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1 代码用铁代码的方式发。

查看全部评分

6 个回复

倒序浏览
黑马网友  发表于 2011-9-5 23:13:11
沙发
楼主 ,如果可以最好能把打印结果列出来,
回复 使用道具 举报
黑马网友  发表于 2011-9-6 08:37:31
藤椅

回复 楼主 的帖子

可能是iso-8859-1 而不是iso8859-1 你还少了个 '-'  反正我就是这么写的,

还有,iso-8859-1是西欧的字符集,不支持中文, 你可以换成UTF-8 或者中文国际编码GB18030试试,这样就不会出现中文问题了

还有在WEB编程的时候可以用iso-8859-1来存储字符串,get传值的时候,里面的中文也是iso-8859-1的, 但如果你想正确的在网页上显示出来,还得转成其它的编码 比如GBK
回复 使用道具 举报
黑马网友  发表于 2011-9-6 10:49:14
板凳
这是一个编码和解码的问题,用GB2313编码时,生成了特定的字节码,然后在解码时由于你没有指定特定的解码表,采用默认的解码表GBK进行解密,由于GBK是GB2312的扩展,所有用GB2312编的码GBK都可以解,所以就可以解出中国,但是如果采用iso8859-1拉丁码表编码,生成了不同于GB2312的字节码,默认的解码表GBK无法找到该字节码对应的汉字或不存在这个字节码,所以出来就乱码了。要搞清楚字符编码的问题,强烈建议看毕老师的视频,其中的day21-07和08有专门讲解字符编码的问题。
回复 使用道具 举报
黑马网友  发表于 2011-9-6 11:39:14
报纸
1.System.in是一个输入流对象,这个输入流使用的默认字符编码集是GB2312
从键盘上读取到的每一个字符(例如中国),操作系统读取时就是读取若干个整数(有些整数用一个字节存放(ASCII)而有些整数用两个字节存

放(中文字符)并且你要知道一个数字对应一个字符这就是字符集),计算机系统将这些整数再与本地字符编码集(GB2312)进行匹配 以此来辨别

输入的是哪些字符。
2.再来Unicode字符集中的字符都是占用两个字节的,Unicode中的ASCII码也一样,例如在ASCII码中a对应的整数是97转化为16进制就是61,而

在Unicode码中a对应的16进制整数是 0061, 就是两个字节了,只是第一个字节的8位二进制数是00000000也就是十六进制的00,所以0061就是

两个字节,也就是说如果使用Unicode的系统读取到的是一个字节的整数它就会当成是ASCII码在前面加上00,将这个数据提升为两个字节
然后来看看你的问题
InputStreamReader isr=new InputStreamReader(System.in,"gb2312");
/*
键盘对应系统输入流默认的编码是GB2312,所以你输入"中国"时,系统会读取到d6d0(中)和b9fa(国),然后用一个字符输入流
new InputStreamReader(System.in,"gb2312");来包装,所以这时就要将d6d0 b9fa(整数)转换为gb2312中对应的字符"中国"
存放到字符输入流中。 String strLine=br.readLine();所以当你从字符输入流中读取数据时就会读取到"中国"这
两个字符(即String strLine = "中国") 也就是说 System.out.println(strLine) =  System.out.println("中国")
所以打印出 中国,然后就是这句Integer.toHexString(strLine.charAt(i))就是将字符转为编码集中对应的整数再
将整数转为16进制整数,因为java中使用的是Unicode编码集,这个编码集中也含有"中国"这两个字符,在Unicode中
"中国"对应的16进制整数就是4e2d 56fd,所以打印出来的是Unicode码
*/
InputStreamReader isr=new InputStreamReader(System.in,"iso8859-1");
/*
按照上面所说的,因为iso8859-1中没有读取到的d6d0 b6fa对应的字符,当要将d6d0 b9fa转换为iso8859-1中对应的字符时得到
的字符就是火星文也就是乱码....
这里是重点哦:上面由d6d0 b9fa得到了iso8859-1的字符虽然是火星文,但是也是有大小的,每个火星文占用1个字节,
因为iso8859-1中的字符都是1个字节的,所以代码String strLine = ??XX(乱码)
Integer.toHexString(strLine.charAt(i))当你用一个字节的火星文来转换成Unicode码时,
系统会将火星文(d6 d0 b9 fa)当作是4个ASCII码,so~java虚拟机 会在这4个ASCII码前面加上一个字节也就是00,
再用System.out.println()打印出来就是00d6 00d0 00b9 00fa。注意这不是GB2313码喔,是Unicode码吗?这我也不知道了
System.out.println(strLine)最后这一句也跟上面一样的道理System.out.println(strLine)=System.out.println("??xx")
回答完毕,这是我自己的理解不知道对不对,希望对你有帮助
*/

评分

参与人数 1技术分 +2 收起 理由
wangfayin + 2 辛苦啦!

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-9-6 11:41:30
地板
排版没排好 不好意思
回复 使用道具 举报
黑马网友  发表于 2011-9-6 14:06:00
7#
soga~谢谢~~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马