Does a Java Scanner Read Escape Characters
For new students, it's often fun to write interactive programs using Scanner in Java. Unfortunately, there are a handful of nasty pitfalls that don't really contribute to a positive experience for those students. As a event, I've come with a warning: be careful with Scanner methods in Java.
Tabular array of Contents
The Problem Students Encounter
When I was learning Java for the first fourth dimension, I never once used Scanner. In fact, I hadn't even touched the utility until I already had two years of industry experience under my belt. But for any reason, the Java curriculum at my current institution uses Scanner extensively, then I figured I'd talk a flake about the pitfalls of some of Scanners methods.
In particular, I want to talk about using Scanner to read user input from the command line. Often times, this is desirable because we want to prompt a user for some input similar their name or a favorite number. Then, we practise some fun calculation and dump the results out to the user. I'll give you lot an example:
Enter your name: Jeremy Howdy, Jeremy!
In this example, we've prompted the user to enter their name, and nosotros've spit it dorsum to them. We can practice this using the following snippet of Java lawmaking:
Scanner input = new Scanner(System.in); System.out.impress("Enter your name: "); String name = input.nextLine(); Organization.out.println("How-do-you-do, " + name + "!"); That'south non too bad! But, what if we want to enquire for a number? Fortunately for us, the Scanner API has a whole host of tokenizer methods like nextLine() to grab any we want from the user and automatically convert it to the appropriate blazon. That said, be careful when using them.
The Explanation Students Want
At this signal, a lot of students will ask me:
What's the big deal? Why should I have to call nextLine() and parse the value by mitt when I can only phone call the proper method directly?
Students Everywhere
And, their concern is completely valid! I'd never ask anyone to practice more work than they take to, so what is the large deal?
Problems
Well, equally it turns out, if you start using methods similar nextLine() without really paying attention to what you lot're parsing, you'll run into a few problems.
Perhaps the most obvious problem is typing bug. For example, let's say nosotros ask the user for a number, and they requite usa a name. Without proper error treatment, our solution will surely crash. That said, this kind of problem isn't too hard to detect or solve. After all, as soon as the user enters invalid text, the solution will crash with a helpful error.
Instead, there'south a much more than nefarious problem that fifty-fifty seasoned programmers volition agree is hard to troubleshoot, and it surfaces when we start to mix usage of the diverse Scanner methods. Take a expect at the following example, and see if you can effigy out what happens when I provide the plan with the number 25 and my proper name.
Scanner input = new Scanner(System.in); Organisation.out.print("Enter your age: "); int age = input.nextInt(); System.out.print("Enter your name: "); String proper noun = input.nextLine(); System.out.println("Your name is " + name + " and y'all are " + historic period); Without digging likewise much into the solution, the average person would say this solution prints "Your name is Jeremy and you are 25". And, to exist honest, I don't fault them for that at all. The logic is there, simply the results aren't. Luckily, I won't leave you hanging!
Bug Hunting
If you've jumped ahead already and tested this solution yourself, you'll have noticed that something strange happens. For starters, our output is incorrect. Instead of "Your name is Jeremy and you are 25", the output volition read "Your name is and you are 25". Right abroad, we'll detect that the name is missing from the output meaning that the name variable is probably storing an empty String.
To make matters worse, when we really run the solution, we'll encounter that we'll merely e'er exist prompted for input one time. After we enter our historic period, the unabridged script will dump to the screen as follows:
Enter your age: 25 Enter your proper noun: Your name is and yous are 25
At this bespeak, nosotros'll be scratching our heads wondering how a phone call to nextLine() just immediately returned an empty String. Fortunately, I have the reply!
Escape Sequences
Whenever nosotros prompt a user for input, they get this fancy line where they tin can dump some text and hit enter. Go along an eye on that final office because it'due south crucial.
That text is equanimous of characters which all have an underlying numeric value. For instance, the alphabetic character 'a' has the numeric value 97 while the number 'seven' has the numeric value 55—oddly plenty. Luckily, in that location'south no need to memorize all these values. Instead, check out an ASCII table
for a list of the first 256 characters.
If nosotros browse that table, we'll find there are a handful of characters that are a fiddling odd. For instance, the entire first cavalcade of that table contains a list of escape sequences. These characters serve a special purpose that isn't always conspicuously visible on the screen.
As it turns out, in that location are a few of these escape sequences that are responsible for denoting line endings in text: x (Line Feed) and 13 (Carriage Return). Depending on the system, whatsoever combination of these two escape sequences may exist used to mark the stop of a line.
Rogue New Lines
For the sake of argument, we'll assume our system marks newlines with the Line Feed grapheme. In Java, the Line Feed character can be written using '\n'. In other words, every time we striking the enter key, we tin can imagine one of these characters sneaking its manner into our text.
Now that we know near the escape sequences, why don't we take some other scissure at bug hunting? I've highlighted the line where the bug begins to manifest itself.
Scanner input = new Scanner(Arrangement.in); System.out.impress("Enter your historic period: "); int age = input.nextInt(); System.out.print("Enter your proper noun: "); Cord name = input.nextLine(); Organization.out.println("Your proper name is " + proper name + " and you are " + historic period); Have you figured out where the bug might be? I'll give you a hint. The nextInt() method only cares to take hold of the side by side number. In other words, information technology leaves behind our rogue new line grapheme ('\n').
After we call nextInt(), we prompt the user to enter their name. At that point, nosotros brand a call to nextLine() which runs upward until the next new line character. Unfortunately, we left one behind when we chosen nextInt(). Every bit a result, nextLine() doesn't have to await until we enter any text. Information technology just returns an empty Cord.
If this is unclear, I recommend trying to feed that lawmaking snippet above a list of ages separated past spaces. For example, check out the following transcript:
Enter your age: 20 xix 31 15 Enter your proper noun: Your name is 19 31 15 and yous are 20
As we can come across, the age is set to the first number in the list (in this case "20"), and the program never prompts for the name. Instead, the residual of the input buffer (in this instance " xix 31 15\northward") is read in as a line and saved as the name.
In the adjacent department, we'll talk near how to deal with the newline that is left behind.
Patch Job
Luckily, in that location are a couple of fixes for this trouble. One relies on catching our mistake and the other relies on fixing the root cause of our problem.
Since we know nosotros've left behind a new line, all we have to do is consume information technology. In other words, we can make an empty phone call to nextLine() before calling it like normal:
Scanner input = new Scanner(System.in); System.out.impress("Enter your age: "); int age = input.nextInt(); Arrangement.out.impress("Enter your name: "); input.nextLine(); Cord name = input.nextLine(); Organisation.out.println("Your name is " + name + " and you are " + historic period); Discover how we've added a telephone call to nextLine() just above the point where nosotros store the proper name. Now, when we leave behind that '\n' graphic symbol, nosotros'll clean up our mess in line 5. Then, we can move on with our lives in line 6.
Alternatively, we can remove this outcome altogether by replacing our nextInt() call with a phone call to nextLine(). Then, we'll need to parse our String to go the integer nosotros desire:
Scanner input = new Scanner(Organization.in); Organization.out.print("Enter your age: "); int historic period = Integer.parseInt(input.nextLine()); System.out.print("Enter your name: "); String proper noun = input.nextLine(); Organization.out.println("Your name is " + name + " and you are " + age); Instead of cleaning up after ourselves, we tin consume the whole line in one go and parse it past hand. Personally, I prefer this option, just both work just fine. In either case, we've completely eliminated this nasty Scanner problems.
Open Forum
Then, moral of the story is be conscientious with the Scanner API. While many of the methods are there for your convenience, mixing them can result in some nasty bugs that are difficult to trace. Of course, it'southward upwards to yous to decide what y'all exercise with this new noesis.
At whatever charge per unit, that's information technology for now! If you lot liked this article or you take some feedback, permit me know in the comments. In addition, if you accept any tips or tricks of your own for dealing with Scanner in Java, don't hesitate to share.
Source: https://therenegadecoder.com/code/be-careful-with-scanner-methods-in-java/
0 Response to "Does a Java Scanner Read Escape Characters"
Post a Comment