从 Java 的 System.in 读取输入的替代方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2982567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
An alternative to reading input from Java's System.in
提问by dvanaria
I'm working on the UVa Online Judge problem set archive as a way to practice Java, and as a way to practice data structures and algorithms in general.
我正在研究 UVa Online Judge 问题集存档,以此作为练习 Java 的一种方式,以及一种通常练习数据结构和算法的方式。
They give an example input file to submit to the online judge to use as a starting point (it's the solution to problem 100).
他们给出了一个示例输入文件,提交给在线法官用作起点(这是第 100 题的解决方案)。
Input from the standard input stream (java.lang.System.in) is required as part of any solution on this site, but I can't understand the implementation of reading from System.in they give in their example solution. It's true that the input file could consist of any variation of integers, strings, etc, but every solution program requires reading basic lines of text input from System.in, one line at a time. There has to be a better (simpler and more robust) method of gathering data from the standard input stream in Java than this:
来自标准输入流 (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));
}
I'm really surprised by this. It looks like something pulled directly from K&R's “C Programming Language” (a great book regardless), minus the access level modifer and exception handling, etc. Even though I understand the implementation, it just seems like it was written by a C programmer and bypasses most of Java's object oriented nature. Isn't there a better way to do this, using the StringTokenizer class or maybe using the split method of String or the java.util.regex package instead?
我真的很惊讶这一点。它看起来像是直接从 K&R 的“C 编程语言”(无论如何都是一本好书)中提取的东西,减去访问级别修饰符和异常处理等。即使我理解实现,它似乎也是由 C 程序员编写的,并且绕过了 Java 的大部分面向对象的特性。有没有更好的方法来做到这一点,使用 StringTokenizer 类或者使用 String 的 split 方法或 java.util.regex 包?
回答by Matthew Flaschen
You definitely don't have to read one byte at a time (you don't in C either, that's what fgetsis for). Depending on what you're doing, you might use BufferedReaderor Scanner:
你绝对不必一次读取一个字节(你也不需要在 C 中,这就是fgets的用途)。根据您在做什么,您可以使用BufferedReader或Scanner:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
Scanner sc = new Scanner(System.in);
BufferedReader has a readLinemethod, while Scanner has a variety of useful methods, including nextLine, nextInt, nextDouble, etc. which handle conversions for you. It also has a regex-based delimiter for reading arbitrary tokens.
BufferedReader中有一个readLine方法,而扫描仪有多种有用的方法,其中包括nextLine,nextInt,nextDouble等其手柄转换为您服务。它还具有用于读取任意标记的基于正则表达式的分隔符。
One thing to understand about Java is that it has a very clear distinction between binary data (Streams) and character data (Readers and Writers). There are default decoders and encoders (as used above), but you always have the flexibility to choose the encoding.
关于 Java 需要理解的一件事是它在二进制数据(Streams)和字符数据(Readers 和 Writers)之间有非常明确的区别。有默认的解码器和编码器(如上所述),但您始终可以灵活地选择编码。

