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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 广驰 中级黑马   /  2012-9-11 19:19  /  2044 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 应广驰 于 2012-9-13 00:36 编辑

这个代码是用Eclipse完成的,输入纯英文没有错误,可是输入中文的时候结果就变了
  1. package io;

  2. import java.io.*;

  3. public class KeyTest
  4. {
  5.         
  6.         public static void main(String[] args) throws IOException
  7.         {
  8.                 BufferedReader isr = new BufferedReader(new InputStreamReader(System.in));
  9.                 BufferedWriter ow = new BufferedWriter(new OutputStreamWriter(System.out));
  10.                 while(true)
  11.                 {
  12.                         String s =  lineRead(isr);
  13.                         if(s.toString().equals("over\r\n"))
  14.                         {
  15.                                 break;
  16.                         }
  17.                         ow.write(s);
  18.                         ow.flush();
  19.                         s = null;
  20.                 }
  21.         }
  22.         
  23.         public static String lineRead(Reader is)//读取控制台的一行文字
  24.         {
  25.                 StringBuilder sb = new StringBuilder();
  26.                 int i = 0;
  27.                 while(true)
  28.                 {
  29.                         try
  30.                         {               
  31.                                 //\r和\n不论是单独出现还是一起出现都放到容器中,
  32.                                 //当两个同时出现代表换行符,一次输入结束
  33.                                 if((i = is.read())=='\r')
  34.                                 {
  35.                                         sb.append((char)i);
  36.                                         if((i = is.read())=='\n')
  37.                                         {
  38.                                                 sb.append((char)i);
  39.                                                 break;
  40.                                         }                                       
  41.                                 }
  42.                                 sb.append((char)i);
  43.                         }
  44.                         catch(IOException io)
  45.                         {
  46.                                 System.out.println("读取失败");
  47.                         }
  48.                 }
  49.                 return sb.toString();        
  50.         }

  51. }
复制代码
一下是输入和输出结果,红色的输入
黑马训练营
黑马训练营
黑马程序员
h'm'c'x黑马程序员
over
'yh'm'c'xh'm'ch'mhover
over
overoveo'voover
over
为什么会出现这种情况

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 赞一个!

查看全部评分

11 个回复

倒序浏览
楼主,我在我的机子上测试了一下,没有问题啊,MyEclipse

黑马训练营
黑马训练营
黑马程序员
黑马程序员
over
回复 使用道具 举报
这个应该是字符编码的问题吧
回复 使用道具 举报
这个估计是eclipse编码的问题吧,我在dos命令下行没有问题
回复 使用道具 举报
is.read()应该是字节吧,一次读一个字节?
编码表不同可能会出现 问题。
为什么不用readLine()
回复 使用道具 举报
  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.OutputStreamWriter;
  6. import java.io.Reader;

  7. public class KeyTest {

  8.         public static void main(String[] args) throws IOException {
  9.                 BufferedReader isr = new BufferedReader(
  10.                                 new InputStreamReader(System.in));
  11.                 BufferedWriter ow = new BufferedWriter(new OutputStreamWriter(
  12.                                 System.out));
  13.                 while (true) {
  14.                         String s = lineRead(isr);
  15.                         if (s.toString().equals("over\r\n")) {
  16.                                 break;
  17.                         }
  18.                         ow.write(s);
  19.                         ow.flush();
  20.                         s = null;
  21.                 }
  22.                 ow.close();
  23.                 isr.close();
  24.         }

  25.         public static String lineRead(Reader is)// 读取控制台的一行文字
  26.         {
  27.                 StringBuilder sb = new StringBuilder();
  28.                 int i = 0;
  29.                 while (true) {
  30.                         try {
  31.                                 // \r和\n不论是单独出现还是一起出现都放到容器中,
  32.                                 // 当两个同时出现代表换行符,一次输入结束
  33.                                 i = is.read();
  34.                                 if (i == '\r') {
  35.                                         // sb.append((char) i);
  36.                                         break;
  37.                                 } else if (i == '\n') {
  38.                                         // sb.append((char) i);
  39.                                         break;
  40.                                 } else {
  41.                                         sb.append((char) i);
  42.                                 }
  43.                         } catch (IOException io) {
  44.                                 io.printStackTrace();
  45.                                 System.out.println("读取失败");
  46.                         }
  47.                 }
  48.                 return sb.toString();
  49.         }

  50. }
复制代码
回复 使用道具 举报
经过2个小时的苦苦思索、测试、简化,一万次后终于理清思路得到简化代码(此代码与楼主代码出现同样的问题):
  1. package com.itheima.test;

  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;

  5. public class KeyTest {

  6.         public static void main(String[] args) throws IOException {
  7.                 BufferedReader isr = new BufferedReader(new InputStreamReader(System.in));
  8.                 while (true) {
  9.                         System.out.println(isr.readLine());
  10.                 }
  11.         }
  12. }
复制代码
我得出结论,问题的出现与控制台的输入有关!
当时我认为:
现象为:输入英文后敲回车,打印正常;复制中文粘贴到控制台后敲回车,打印正常;快速拼写出中后敲回车,打印正常;拼写中途稍作停顿后,敲空格让中文显现在控制台上,然后敲回车,打印异常,多出现了一些有规律的拼音字母!

无图无真相嘛。我要截真相图时,难倒我了。。。。。因为,有时候会印证我的结论,有时不能。

终于又在一万次测试之后,我终于测试出问题的根源!!!!!

原因居然还是控制台录入中文的问题。

后来我在想,eclipse,呵呵,老外用0、1与英语开发的编程语言工具嘛。对中文支持效果不佳,极不稳定,我想得出一个出错的准确规律,无奈夜已深,明早要去一家公司面试,想想作罢。总之各种情况都会有,对中文兼容不好就对了。
这是在GBK编码下测试的。
其它格式就别想了,又不支持中文编码,情况更糟糕。
  1. 你好
  2. 你好
  3. 你好
  4. ni'h你好



  5. nihani'hnin



复制代码
太晚了 就不截图了。反正就是这个意思。大家以后要写程序,做交互,让客户输入内容,尽量给出选项提示信息,让客户输入阿拉伯数字选择避免此类问题就行了。

唉。为这道题目花了我三个小时。版主至少给三分把。明天的面试都没做准备。大家祝我明天好运吧。

评分

参与人数 1技术分 +2 收起 理由
职业规划-刘倩老师 + 2 赞一个!继续加油!!!

查看全部评分

回复 使用道具 举报
广驰 中级黑马 2012-9-12 10:31:43
8#
寇龙飞 发表于 2012-9-12 00:32
经过2个小时的苦苦思索、测试、简化,一万次后终于理清思路得到简化代码(此代码与楼主代码出现同样的问题 ...

我倒是也想过, eclipse兼容的问题,可是对为什么会出现这样的情况,有些好奇, eclipse是怎样实现录入的,不过还是谢谢了
回复 使用道具 举报
广驰 中级黑马 2012-9-12 10:36:45
9#
黑马-李勇 发表于 2012-9-11 21:34
is.read()应该是字节吧,一次读一个字节?
编码表不同可能会出现 问题。
为什么不用readLine() ...

我这个是自己模拟的readLine(),再说java定义好的readLine()底层也是用的read()吧
回复 使用道具 举报
其实这问题和eclipse没有关系,这和操作系统的语言环境有关.如果你的操作系统的语言环境不是中文(中国),那么你想输入或输出中文,就必须要在在实例化输入流或输出流对象时,要传入"gbk"的编码,这样才可以读取到中文字符.由于你的操作系统的语言环境不是中文(中国),比如说如果是英语(美国),那么就要将输入流取得的中文字符先用某一种编码格式(比如说utf-8)编码为英语(美国)语言环境可以接受的字节,再将编码后的字节以同一种编码格式(utf-8)解码为英语(美国)语言环境可以接受的字符,这样就可以在控制台中打印出来了,以下是代码示例:
  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.OutputStreamWriter;
  6. import java.io.Reader;
  7. import java.io.UnsupportedEncodingException;

  8. public class KeyTest {

  9.         public static void main(String[] args) throws IOException {
  10.                 BufferedReader isr = new BufferedReader(new InputStreamReader(
  11.                                 System.in, "gbk"));

  12.                 BufferedWriter ow = new BufferedWriter(new OutputStreamWriter(
  13.                                 System.out, "gbk"));
  14.                 while (true) {
  15.                         String s = lineRead(isr);
  16.                         if (s.equals("over")) {
  17.                                 break;
  18.                         }
  19.                         ow.write(s);
  20.                         ow.flush();
  21.                         s = null;
  22.                 }
  23.                 ow.close();
  24.                 isr.close();
  25.         }

  26.         public static String lineRead(Reader is)// 读取控制台的一行文字
  27.         {
  28.                 StringBuilder sb = new StringBuilder();
  29.                 int i = 0;
  30.                 String string = null;
  31.                 while (true) {
  32.                         try {
  33.                                 // \r和\n不论是单独出现还是一起出现都放到容器中,
  34.                                 // 当两个同时出现代表换行符,一次输入结束
  35.                                 i = is.read();
  36.                                 if (i == '\r') {
  37.                                         break;
  38.                                 } else if (i == '\n') {
  39.                                         break;
  40.                                 } else {
  41.                                         sb.append((char) i);
  42.                                 }
  43.                         } catch (IOException io) {
  44.                                 io.printStackTrace();
  45.                                 System.out.println("读取失败");
  46.                         }
  47.                 }
  48.                 try {
  49.                         // 必须要将把从gbk语言环境中取得的中文字符先编码为utf-8格式的字节,再将此编码后的
  50.                         // 字节解码为utf-8格式的字符,才可以在各种不同语言环境的操作系统上正确显示出中文字符,
  51.                         // 因为utf-8是全球通用的编码格式,包括了所有国家使用的语言文字.
  52.                         string = new String(sb.toString().getBytes("utf-8"), "utf-8");
  53.                 } catch (UnsupportedEncodingException e) {
  54.                         e.printStackTrace();
  55.                 }
  56.                 return string;
  57.         }

  58. }
复制代码
回复 使用道具 举报
马镱洵 发表于 2012-9-12 15:05
其实这问题和eclipse没有关系,这和操作系统的语言环境有关.如果你的操作系统的语言环境不是中文(中国),那么 ...

但是我的操作系统语言环境是中文的啊
回复 使用道具 举报
应广驰 发表于 2012-9-12 16:34
但是我的操作系统语言环境是中文的啊

中文的操作系统自然就不需要给输入和输出流传入"gbk"编码了:
  1. BufferedReader isr = new BufferedReader(
  2.                                 new InputStreamReader(System.in));
  3.                 BufferedWriter ow = new BufferedWriter(new OutputStreamWriter(
  4.                                 System.out));
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马