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

6
我正在练习Java编程,以及数据结构和算法,所以选择了UVa Online Judge问题集档案作为练习的方式。
他们提供了一个示例输入文件,可用作起点(它是问题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&R的《C编程语言》(一本很好的书)直接提取出来的,只是少了访问级别修饰符和异常处理等。即使我理解了其实现方式,它似乎仍然是由C程序员编写的,并绕过了Java大部分面向对象的特性。难道没有更好的方法来做这件事情吗?比如使用StringTokenizer类或者String的split方法,或者java.util.regex包中的方法?


4
我查看了代码并哭了。 - Yacoby
2
你在用 MS Word 作为 IDE 吗?指着那些无法编译的卷曲引号。 - BalusC
哈。是的,我通常会在Word中编写内容进行拼写检查等操作,然后再发布,这只是习惯而已。不过你说得对,下次我会记住的。该死的卷引号。 - dvanaria
1
你的真正IDE不做拼写检查?太原始了! - Stephen C
1个回答

11
你绝不需要一个字节一个字节地读取(在C中也不需要,这就是fgets的作用)。根据你的需求,你可以使用BufferedReaderScanner
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

Scanner sc = new Scanner(System.in);

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

需要理解Java的一件事是,它在二进制数据(流)和字符数据(Reader和Writer)之间有非常明确的区别。有默认的解码器和编码器(如上所示),但您始终可以选择编码方式。


这些的唯一缺点是它们是带缓冲的,如果你在readline方法中每次重新创建它们,当多行同时输入时(使用java -jar...<testcase.txt测试程序时会发生),你有可能丢失输入。所以创建它们一次并多次重复使用。 - Ferrybig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接