前几天帮助室友搞定bug的时候,出现了一个Scanner读取中文乱码的问题。
问题描述如下:使用Scanner读取从windows的cmd窗口中的中文的时候出现乱码。
问题代码如下:
import java.util.Scanner;
public class Test{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String line = sc.next();
System.out.println(line);
System.out.println("销售经理");
}
}
问题截图:
分析原因:这个乍一看就是个编码解码字符集不一致导致的乱码问题嘛。
但是,仔细想想,这到底是个怎样的过程呢?而且这个问题不是一定会发生的,比如在我室友的电脑上就会乱码,但是到我自己的电脑上就不乱码了。所以这里面一定有古怪!
经过我多方走访资料,发现,主要问题是出在windows的cmd窗口的编码字符集和jvm本身默认的解码字符集不一致导致的乱码。
大家想想,Scanner(System.in)是从控制台读取字节流的,那么将中文字符转换为字节流是谁来完成的呢?当然是由你输入的控制台来完成的啦。
所以我们就需要搞清楚cmd窗口的编码集和jvm本身的解码集(其实编码和解码都是一个字符集,这里只是为了更清楚的描述这个过程)。
我们可以使用这样一组过程来查看cmd窗口字符集:
查看当前windows字符集
开始--》运行---》cmd----》
键入:chcp
活动的代码页:936
在命令提示符的“菜单”上,右击-----》属性----》当前代码页 936(ANSI/OEM -简体中文GBK)。
然后可以通过这样一组过程来查看jvm的字符集:
可以使用System.out.println(Charset.defaultCharset());来查看jvm默认的字符集。
对比发现:由于我自己的电脑二者是一致的,都是GBK字符集,所以没有乱码。测试代码如下:
import java.util.Scanner;
import java.lang.Exception;
import java.nio.charset.Charset;
public class Test{
public static void main(String[] args){
//第一种方法测试
//Scanner sc = new Scanner(System.in,"GBK");修改Scanner转换字节流到字符的解码集
Scanner sc = new Scanner(System.in);
String line="";
//String line = sc.next();
try{
//第二种方法测试
line = new String(sc.next().getBytes("GBK"),"GBK");
//line = sc.next();
}catch(Exception e){
e.printStackTrace();
}
System.out.println(Charset.defaultCharset());
System.out.println(line);
System.out.println("销售经理");
}
}
总结:
其实乱码的根本原因就是编码与解码的时候采用的字符集不一致导致的,所以出现这种问题,最根本的解决办法就是搞清楚这个过程是怎样编码和解码的,找到关键的两个过程对应的平台,查看他们的字符集,再对症下药!



