从Java的System.in读取输入的替代方法

时间:2010-06-05 23:43:17

标签: java input standards system.in

我正在研究UVa Online Judge问题集存档作为练习Java的方法,并且作为一种练习数据结构和算法的方法。

他们提供了一个示例输入文件,提交给在线裁判以作为起点(这是问题100的解决方案)。

标准输入流(java.lang.System.in)的输入是本网站上任何解决方案的一部分,但我无法理解他们在示例解决方案中提供的System.in读取的实现。确实,输入文件可以包含整数,字符串等的任何变化,但每个解决方案程序都需要从System.in读取基本的文本输入行,一次一行。必须有一个更好的(更简单和更健壮的)从Java标准输入流收集数据的方法,而不是:

public static String readLn(int maxLg) {
    byte lin[] = new byte[maxLg];
    int lg = 0, car = -1;
    String line = “”;
    try {
        while (lg < maxLg) {
            car = System.in.read();
            if ((car < 0) || (car == ‘\n’)) {
                break;
            }
            lin[lg++] += car;
        }
    } catch (java.io.IOException e) {
        return (null);
    }
    if  ((car < 0) && (lg == 0)) {
        return (null); // eof
    }
    return (new String(lin, 0, lg));
}   

我对此感到非常惊讶。它看起来像直接从K&amp; R的“C编程语言”(无论如何都是一本好书)中提取,减去访问级别修饰符和异常处理等。即使我理解了实现,它看起来好像是由C编写的程序员并绕过Java的大多数面向对象的本质。有没有更好的方法,使用StringTokenizer类或者使用String的split方法或java.util.regex包?

1 个答案:

答案 0 :(得分:9)

你绝对不必一次读取一个字节(你也不用C语言,这就是fgets的用途)。根据您的工作情况,您可以使用BufferedReaderScanner

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

Scanner sc = new Scanner(System.in);

BufferedReader有readLine方法,而Scanner有各种有用的方法,包括nextLinenextIntnextDouble等,可以为您处理转化。它还有一个基于正则表达式的分隔符,用于读取任意标记。

要理解Java的一点是它在二进制数据(Streams)和字符数据(读者和写者)之间有非常明显的区别。有默认的解码器和编码器(如上所述),但您始终可以灵活地选择编码。