Limiting string length is one of the more obvious areas where readers shines over scanners. Though most of the time, you don't really need a scanner and a reader will do. The trade off for using scanners is difficult error handling, but it isn't worth it in most cases.
(Ignore the writer parts, you could use print stream if you want. I normally use writers rather than print streams for similar reasons to why I prefer readers to scanners :P Also, ignore that the app is callable. You can just as easily set this to run straight from void main. It's just how I do things.)
Phone number is a bad demonstrary example because it involves parsing various number formats rather than the number itself. I will ask the user for two four digit numbers instead.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileDescriptor;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.Callable;
public final class LimitedDigitInputApp implements Callable
{
private final Writer OUT;
private final BufferedReader IN;
private final String NEW_LINE;
public static void main(final String... args)
throws IOException
{
new LimitedDigitInputApp(
new BufferedWriter(new FileWriter(FileDescriptor.out)),
new BufferedReader(new FileReader(FileDescriptor.in)),
System.lineSeparator()
).call();
}
public LimitedDigitInputApp(final Writer out, final BufferedReader in, final String lineSeparator)
{
this.OUT = out;
this.IN = in;
this.NEW_LINE = lineSeparator;
}
public Void call()
throws IOException
{
char[] input = new char[4];
this.OUT.append("Please enter a four digit number: ").flush();
this.IN.read(input);
final long NUMBER1 = Integer.parseInt(String.valueOf(input));
this.IN.readLine(); // readline reads in the enter after the number.
this.OUT.append("Please enter another four digit number: ").flush();
this.IN.read(input);
final long NUMBER2 = Integer.parseInt(String.valueOf(input));
this.IN.readLine();
this.OUT.append(this.NEW_LINE)
.append("You entered ")
.append(String.valueOf(NUMBER1))
.append(" and ")
.append(String.valueOf(NUMBER2))
.append('.')
.append(this.NEW_LINE)
.flush();
return null;
}
}
The basic idea is:
- Make a buffered reader for user input.
- Make a character array that will temporarily store input.
- Call read(char[]) on the reader to get your input.
- Use a parsing method (for example Integer.parseInt) to parse the input into a number.
- Call readLine() to clear the rest of the line.
If your user input a string that was too short, the parsing method will throw a NumberFormatException because it will hit the new line character. If your user input a string that was too long, the rest will be ignored. Though you could check that this.IN.readLine().equals("") to make sure there are no extra characters and throw another NumberFormatException if there are.
Parsing the string is completely up to you. You could use a parsing method that already exists or make your own. For example, you might be asking for a street address and only care that it isn't too long. You might just strip out any new line characters and continue with your program.
I hope this helps! :)