It's been a while since I started learning Java and I have finally gotten into the habit of terminating my lines again. Learning python really did not help my Java learning curve but I still got through it. The building process has become much smoother and I honestly feel as though I have become a more efficient coder. These thoughts inspired the upcoming series and before I dive into the post, let me explain what this new series is all about.
I'll basically be covering all my biggest pitfalls and obstacles that I encountered while learning the language and just topics in general that I felt weren't covered as well as much as I would have liked. That being said, lets dive right in.
Reading in a String after an Integer
For learning sake, I will start at the beginning. I'm not going all the way back to variables, just going back up until the point where we learned about receiving input from the terminal. And that is by using the Scanner class. Before we can even make use of Scanner objects we need to import it, like so.
import java.util.Scanner;
This enables us to instantiate (create) as many Scanner objects as we like. Usually, you only ever need one. When we create a new Scanner object, we pass in System.in
as a paramater to its constructor. Once we have created the Scanner object we can use the Scanner method, nextLine()
, to prompt the user for input in the terminal.
Scanner input = new Scanner(System.in); // creating new Scanner Object
System.out.print("Please enter your name: "); //prompting the user for a value
String name = input.nextLine();
System.out.println("Hello " + name);
You may notice that I use the System.out.print()
method instead of the usual println()
. This is because, print()
does not add a newline character at the end of the string and this allows us to receive input on the same line that we print on. This is just the standard convention when inserting input into the terminal.
The scanner class allows to receive input from the terminal. When receiving input, in most languages, the default data type of input from the terminal is a String and if you wanted an Integer or Float you would have to then cast or convert the input to the data type of interest. In Java, the Scanner class allows us to read in input as Double Integer or a Float using the methods nextInt()
and nextDouble()
. So if we were to continue from the previous snippet...
System.out.printf("Please enter your age: ");
int age = input.nextInt();
if (16 < age && age < 21) {
System.out.println("Consider yourself part of the most elite generation that has set foot on Earth");
} else {
System.out.println("Sorry you didn't make the cut :(");
}
The Problem 💢
If you are wondering, "what was so mind boggling that I had to mention it in this series?". Well let me explain...
There are times where you will want to read in a String after reading in an Integer, Double or Float etc. If you do so, you might see something strange occur. For example.
Scanner in = new Scanner(System.in);
System.out.print("How old are you? :")
int age = input.nextInt(); // Let say I enter 26 at runtime
System.out.print("What is your name? :)
int name = input.nextString(); // I will not be allowed to enter input here
System.out.printf("%s is %d years old", name, age); // The output will be (" is 26 years old")
When this code executes Java does not give me a chance to input anything for the name variable. It sort of just skips that line and executes the final line of code. The value of the name variable will be an empty string. You can take my word for it or if you are still skeptical, copy the snippet above and run the code yourself. Quickest way to do that is use repl.it. Now that you believe me, let me explain what is happening.
When the method input.nextLine()
is called Scanner object will wait for you, the user, to hit enter. That will tell the Scanner Object that you have finished entering text and to stop receiving input. You should also know that the enter key is a character. I will refer to this character as the the return character. The return character is represented by a \n
in java strings. In other words, when java reads a String and it comes across the return character, java does not insert the characters "\n" into the text, instead it use it to format text by moving what ever is left of the string onto the next line.
What I'm trying to get across is that the return character will be the last character in the string of an input. Therefore, the Scanner will consider everything before the return character as the actual input.
The nextLine()
method can easily convert the input to a string because that is the data type that it came in. It will simply read in all the characters and remove the last character. I like to think of this process as cleaning up the enter character.
The Scanner method nextInt()
does not do the same cleanup. When you enter a value and hit enter. There is a newline character left at the end of that input. It just sort of hangs around in the terminal, for reasons I'm still unsure of, until more input is required from the user. This means the next time you call nextLine()
. It considers the previous newline character as the signal that you have already entered your input, leaving you with an empty string. Now you should have an idea of what is going on in the next picture.
The Solution 💡
The are different ways to get around this. One way is to simply read in all your Strings before your Integers and Floats etc. According to me, that does not qualify as a ✌️solution✌️ in my book. The best solution is to simply call nextLine()
twice. Once, to remove the newline character that is hanging in the terminal, and a second time for us to read in a value as per normal.
System.out.print("How old are you?: ");
int age = input.nextLine();
System.out.print("What is your name?: ");
input.nextLine(); // this will remove the hanging return character
String name = input.nextLine();
Conclusion
All the problems I've had always had some clever trick or solution to it. I've come to realise that Java is one of the most respected language amongst the tech community. I'm starting to wonder whether its because people use it a lot and found it useful, or because of these niche problem that made it so difficult to conquer. Either way, I've enjoyed learning the language and hope this would help a poor soul that has been stifled by this trivial issue.
As always, thanks for the read and Happy Coding💻!
Top comments (2)
Something to keep in mind is that the problems you're experiencing have to do with the Scanner utility, not with the Java language as such. In general, Java tends to have much less gotchas and magic than many other popular languages.
Best of luck on your learning journey!
Hello just ran into this learning JAVA also :) thanks for the article