我正在研究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包?
答案 0 :(得分:9)
你绝对不必一次读取一个字节(你也不用C语言,这就是fgets的用途)。根据您的工作情况,您可以使用BufferedReader或Scanner:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
Scanner sc = new Scanner(System.in);
BufferedReader有readLine
方法,而Scanner有各种有用的方法,包括nextLine
,nextInt
,nextDouble
等,可以为您处理转化。它还有一个基于正则表达式的分隔符,用于读取任意标记。
要理解Java的一点是它在二进制数据(Streams)和字符数据(读者和写者)之间有非常明显的区别。有默认的解码器和编码器(如上所述),但您始终可以灵活地选择编码。