Home Scanners
Token and line-based processing
Do not try and mix together token and line-based processing with the same scanner. Doing so will almost always result in hard-to-debug bugs.
This style rule is less of a style rule, and more of a "if you do this, you'll have a bug rule". Most style rules exist because they help prevent bugs in one way or another, but this particular rule is unusually direct.
If you mix together token-based processing (next()
, nextInt()
,
etc) and line-based processing (nextLine()
), your code will not work:
Scanner scan = new Scanner(System.in); Integer number = scan.nextInt(); // ... some code here String line = scan.nextLine(); // bug!
It's not important to understand why exactly this happens, but to summarize, this potential bug has to do with how Scanners internally work. When you call a token method, the scanner will internally advance to the end of the current word, number, what-have-you. When you call a line method, the scanner will internally advance to the next newline.
When you call a token and then a line method, the scanner will internally advance to the end of the word and then move exactly one character over to the following newline, instead of asking the user to plug in more input.
To avoid this potential bug, you should always immediately decide when you create a scanner whether or not you intend to use that as a token scanner, or a line scanner, and stick with that decision throughout your program.
It is also ok to create a new scanner if you need to grab tokens from a specific line. For example, the following is ok:
Scanner lineScan = new Scanner(System.in); while (lineScan.hasNextLine()) { String currentLine = lineScan.nextLine(); Scanner tokenScan = new Scanner(currentLine); while (tokenScan.hasNext()) { String token = tokenScan.next(); // Do something with token } }