An alternative to reading input from Java's System.in
Asked Answered
S

1

6

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.

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).

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:

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?

Stalk answered 5/6, 2010 at 23:43 Comment(4)
I looked at the code and criedFortunetelling
You're using MS Word as IDE? Points to those curly quotes which won't compile.Bela
Ha. Yes, i usually write up stuff in Word to spell check, etc before posting, just habit. Good point though, I'll remember for next time. Stupid curly quotes.Stalk
your real IDE doesn't do spelling checking? How primitive!Spermous
P
11

You definitely don't have to read one byte at a time (you don't in C either, that's what fgets is for). Depending on what you're doing, you might use BufferedReader or Scanner:

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

Scanner sc = new Scanner(System.in);

BufferedReader has a readLine method, 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.

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.

Protoactinium answered 5/6, 2010 at 23:46 Comment(1)
The only downside of those are that they are buffered, and if you recreate them every time in the readline method, you are at risk of losing input if multiple lines are input at the same time (happens when the program is tested using java -jar ... < testcase.txt), So make them once and reuse themJusticiar

© 2022 - 2024 — McMap. All rights reserved.