The last three characters, minus one
A easy Java puzzle in the off-by-one errors family. One line below contains a real bug. Try to spot it first, then read why it fails and how to fix it.
Highlighted: line 4. Play this one as a puzzle without the answer.
What is wrong
substring takes an inclusive start and an exclusive end. Ending at length - 1 stops before the last character, so the result has two characters ("42") instead of three.
The fix
How to avoid it next time
When a substring should run to the end, omit the end argument. Check the length of the returned text in a test.
Want the background? Read Strings: immutability, equality, common methods in the Java concepts library.
About off-by-one errors
Loop bounds, indexes and lengths are the oldest source of bugs in programming. Java arrays and lists are zero-based, so the last valid index is length minus one, and ranges such as substring use an inclusive start and an exclusive end.
In code review: Check every loop condition against the first and last element, and ask what happens with zero or one element. Prefer enhanced for loops, streams and library methods that remove manual index arithmetic.
More puzzles in this family
Frequently asked questions
What is the bug in "The last three characters, minus one"?
substring takes an inclusive start and an exclusive end. Ending at length - 1 stops before the last character, so the result has two characters ("42") instead of three. The faulty line is line 4: return card.substring(card.length() - 3, card.length() - 1);
How do I fix it?
Replace it with: return card.substring(card.length() - 3);. When a substring should run to the end, omit the end argument. Check the length of the returned text in a test.
How do I catch off-by-one errors in code review?
Check every loop condition against the first and last element, and ask what happens with zero or one element. Prefer enhanced for loops, streams and library methods that remove manual index arithmetic.
Is there a new puzzle every day?
Yes. The daily Spot the Bug puzzle picks one of these snippets for each UTC day, with the difficulty set by the weekday. Your streak is stored only in your browser.