System.out.println repeating itself - java

Would anyone point me in the right direction, of why when i use a for loop the println function comes up two times in the output. Thanks
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of employees to calculate:");
int numberEmployees = scan.nextInt();
for(int i=0; i<numberEmployees; i++){
System.out.println("Enter First Name:");
name = scan.nextLine();
System.out.println("Enter Last Name:");
last = scan.nextLine();
System.out.println("Enter Document #:");
document = scan.nextInt();
System.out.println("Enter Basic Salary");
basicSalary = scan.nextInt();
System.out.println("Enter # of Hours");
hours = scan.nextInt();
}
}
OUTPUT
Enter the number of employees to calculate:
1
Enter First Name:
Enter Last Name:
daniel
Enter Document #:

The problem is that when you entered 1 with a new line, the nextInt() function doesn't remove the newline that you had from entering in the 1. Change your calls to scan.nextInt() to Integer.parseInt(scan.nextLine()) and it should behave the way you want.
To further explain; here's stuff from the Java API.
A Scanner breaks its input into tokens using a delimiter pattern,
which by default matches whitespace. The resulting tokens may then be
converted into values of different types using the various next
methods.
and
The next() and hasNext() methods and their primitive-type companion
methods (such as nextInt() and hasNextInt()) first skip any input that
matches the delimiter pattern, and then attempt to return the next
token. Both hasNext and next methods may block waiting for further
input.
So, what evidently happens (I didn't see anything on the page to confirm it) is that after next(), hasNext(), and their related methods read in a token, they immediately return it without gobbling up delimiters (in our case, whitespace) after it. Thus, after it read in your 1, the newline was still there, and so the following call to nextLine() had a newline to gobble and did so.

It appears that the newline character remains in your input after the first entry. When the next input is requested, the Scanner sees a newline character and interprets it as the end of the input. This makes it appear to skip every other input request. I would suggest checking out the Java API docs as to the exact behavior of Scanner's methods.

Related

What is memory buffer? And how different Scanner class methods operate on the probable issues of line breaks, white spaces etc.?

I am having trouble understanding how memory buffer works when I am working with Scanner class methods such as hasNextInt() hasNextDouble() etc. Considering the following code,
Scanner in = new Scanner(System.in);
int number;
do {
System.out.print("Enter a positive integer: ");
while (!in.hasNextInt()) {
System.out.println("It's not an integer!");
in.next();
}
number = in.nextInt();
} while (number <= 0);
System.out.println("Your number is " + number);
The output for some random values:
Enter a positive integer: five
It's not an integer!
-1
Enter a positive integer: 45
Your number is 45
What actually happens here? At line 1 when I enter five the nested while loop runs. What is the job of in.next()? After I enter five it says It's not an integer! But why doesn't it ask again: Enter a positive integer: ? Basically, I want the corresponding output to be like this:
Enter a positive integer: five
It's not an integer!
Enter a positive integer: -1
It's not a positive integer!
Enter a positive integer: 45
Your number is 45.
I would appreciate a brief and intuitive explanation how white spaces, line breaks are handled in input validation? And what is memory buffer? And how different methods of Scanner class like next(), nextLine(), nextInt(), nextDouble() etc. operate?
Also, how do I avoid repetition of It's not an integer!
Enter a positive number: five
It's not an integer!
one two three
It's not an integer!
It's not an integer!
It's not an integer!
10
Your number is 10
And finally, why many recommend try catch?
To start with, 0, -1, -66, 2352, +66, are all Integer values so you can't very well decide to designate them as otherwise. Your validation response should really be:
System.out.println("It's not a positive integer value!");
I personally never use those nextInt(), nextDouble(), etc methods unless I want blind validation. I just stick with a single loop, and utilize the nextLine() method along with the String#matches() method (with a small Regular Expression). I also don't really care for using a try/catch to solve a situation where I don't have to.
Scanner in = new Scanner(System.in);
int number = 0;
while (number < 1) {
System.out.print("Enter a positive integer (q to quit): ");
String str = in.nextLine();
if (!str.equals("") && String.valueOf(str.charAt(0)).equalsIgnoreCase("q")) {
System.exit(0);
}
// If a string representation of a positive Integer value
// is supplied (even if it's prefixed with the '+' character)
// then convert it to Integer.
if (str.matches("\\+?\\d+") && !str.equals("0")) {
number = Integer.parseInt(str);
}
// Otherwise...
else {
System.err.println(str + " is not considered a 'positive' integer value!");
}
}
System.out.println("Your number is " + number);
In this particular use-case, I actually find this more versatile but then, perhaps that's just me. It doesn't matter what is entered, you will always get a response of one form or another and, you have a quit option as well. To quit either the word quit or the letter q (in any letter case) can be supplied.
People like to utilize the try/catch in case a NumberFormatException is thrown by nextInt() because a white-space or any character other than a digit is supplied. This then allows the opportunity of displaying a message to console that an invalid input was supplied.
Because the Scanner class is passed System.in within its' constructor (in is an object of InputStream) it is a Stream mechanism and therefore contains a input (holding) buffer. When anything is typed to the Console Window it is place within the input buffer until the buffer is read by any one of the next...() methods.
Not all Scanner class methods like next(), nextInt(), nextDouble(), etc, completely utilize everything contained within the stream input buffer, for example, these methods do not consume whitespaces, tabs, and any newline characters when the ENTER key is hit. The nextLine() method however does consume everything within the input buffer.
This is exactly why when you have a prompt for a User to supply an Integer value (age) and you use the nextInt() method to get that data and then directly afterwords you prompt for a string like the User's name using the nextLine() method, you will notice that the nextLine() prompt is skipped over. This is because there is still a newline character within the input buffer that wasn't consumed by the nextInt() method and now forces the nextLine() method to consume it. That ENTER that was done in the previous nextInt() method is now passed into the nextLine() method thus giving the impression that the prompt was bypassed when in reality, it did receive a newline character (which in most cases is pretty much useless).
To overcome this particular situation the easiest thing to do is to consume the ENTER key newline character by adding scanner.nextLine(); directly after a int myVar = scanner.nextInt(); call. This then empties the input buffer before the String name = scanner.nextLine(); comes into play.

Scanner interfering with another

So I am trying to make a code that will prompt the user to either use a basic calculator, or a word counter that displays how many words are in a given sentence entered by the user, this is done using methods. I have figured out how to properly set up the calculator, but the word counter is giving me some issues:
public static int wordCounter(String str){
String words[]=str.split(" ");
int count=words.length;
return count;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("What do you want to do( calculator(0)/word counter(1) )? ");
//This runs and I select '1' for word counter
int choice = input.nextInt(); //Input the choice here
if (choice == 0) {
// It runs this selection statment, and since zero is not selected,
//it runs the word Counter branch
calculator();
}else{
System.out.println("Please enter a sentence:"); // Tells me to enter a sentence
String sentence=input.nextLine();
//^ This input is completely skipped and goes
//right to the 'System.out.print(); Statement.
System.out.print("There are "+ wordCounter(sentence) + " words in the sentence.");
//^ This prints a 1 immediately after the branch is selected with '1'
}
}
I'm not sure where it is going wrong since this only happens while it is in the if/else statement. Doing some testing also showed me that it seems that the first scanner "int choice=input.nextInt()" Is somehow interfering with the second scanner for the string. Any ideas keeping a similar formatting would be greatly appreciated.
Please forgive my formatting, it may not look great.
nextLine() will only return the remainder of the current line being scanned. Since you would have pressed enter after selecting the number, all it will capture is an empty string.
To fix it, just add a nextLine() directly after you get the integer.
public String nextLine()
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.
https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine()
The problem is when you enter the number int choice = input.nextInt() it's only scanning the integer, not the newline. So when you call input.nextLine() it instantly returns an empty string. One way to fix this would be to replace that line with
int choice = Integer.parseInt(input.nextLine());

What's the difference between next() and nextLine() methods from Scanner class?

What is the main difference between next() and nextLine()?
My main goal is to read the all text using a Scanner which may be "connected" to any source (file for example).
Which one should I choose and why?
I always prefer to read input using nextLine() and then parse the string.
Using next() will only return what comes before the delimiter (defaults to whitespace). nextLine() automatically moves the scanner down after returning the current line.
A useful tool for parsing data from nextLine() would be str.split("\\s+").
String data = scanner.nextLine();
String[] pieces = data.split("\\s+");
// Parse the pieces
For more information regarding the Scanner class or String class refer to the following links.
Scanner: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
String: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
next() can read the input only till the space. It can't read two words separated by a space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
For reading the entire line you can use nextLine().
From JavaDoc:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
next(): Finds and returns the next complete token from this scanner.
nextLine(): Advances this scanner past the current line and returns the input that was skipped.
So in case of "small example<eol>text" next() should return "small" and nextLine() should return "small example"
The key point is to find where the method will stop and where the cursor will be after calling the methods.
All methods will read information which does not include whitespace between the cursor position and the next default delimiters(whitespace, tab, \n--created by pressing Enter). The cursor stops before the delimiters except for nextLine(), which reads information (including whitespace created by delimiters) between the cursor position and \n, and the cursor stops behind \n.
For example, consider the following illustration:
|23_24_25_26_27\n
| -> the current cursor position
_ -> whitespace
stream -> Bold (the information got by the calling method)
See what happens when you call these methods:
nextInt()
read 23|_24_25_26_27\n
nextDouble()
read 23_24|_25_26_27\n
next()
read 23_24_25|_26_27\n
nextLine()
read 23_24_25_26_27\n|
After this, the method should be called depending on your requirement.
What I have noticed apart from next() scans only upto space where as nextLine() scans the entire line is that next waits till it gets a complete token where as nextLine() does not wait for complete token, when ever '\n' is obtained(i.e when you press enter key) the scanner cursor moves to the next line and returns the previous line skipped. It does not check for the whether you have given complete input or not, even it will take an empty string where as next() does not take empty string
public class ScannerTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int cases = sc.nextInt();
String []str = new String[cases];
for(int i=0;i<cases;i++){
str[i]=sc.next();
}
}
}
Try this program by changing the next() and nextLine() in for loop, go on pressing '\n' that is enter key without any input, you can find that using nextLine() method it terminates after pressing given number of cases where as next() doesnot terminate untill you provide and input to it for the given number of cases.
next() and nextLine() methods are associated with Scanner and is used for getting String inputs. Their differences are...
next() can read the input only till the space. It can't read two words separated by space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
import java.util.Scanner;
public class temp
{
public static void main(String arg[])
{
Scanner sc=new Scanner(System.in);
System.out.println("enter string for c");
String c=sc.next();
System.out.println("c is "+c);
System.out.println("enter string for d");
String d=sc.next();
System.out.println("d is "+d);
}
}
Output:
enter string for c
abc def
c is abc
enter string for d
d is def
If you use nextLine() instead of next() then
Output:
enter string for c
ABC DEF
c is ABC DEF
enter string for d
GHI
d is GHI
In short: if you are inputting a string array of length t, then Scanner#nextLine() expects t lines, each entry in the string array is differentiated from the other by enter key.And Scanner#next() will keep taking inputs till you press enter but stores string(word) inside the array, which is separated by whitespace.
Lets have a look at following snippet of code
Scanner in = new Scanner(System.in);
int t = in.nextInt();
String[] s = new String[t];
for (int i = 0; i < t; i++) {
s[i] = in.next();
}
when I run above snippet of code in my IDE (lets say for string length 2),it does not matter whether I enter my string as
Input as :- abcd abcd or
Input as :-
abcd
abcd
Output will be like
abcd
abcd
But if in same code we replace next() method by nextLine()
Scanner in = new Scanner(System.in);
int t = in.nextInt();
String[] s = new String[t];
for (int i = 0; i < t; i++) {
s[i] = in.nextLine();
}
Then if you enter input on prompt as -
abcd abcd
Output is :-
abcd abcd
and if you enter the input on prompt as
abcd (and if you press enter to enter next abcd in another line, the input prompt will just exit and you will get the output)
Output is:-
abcd
From javadocs
next() Returns the next token if it matches the pattern constructed from the specified string.
nextLine() Advances this scanner past the current line and returns the input that was skipped.
Which one you choose depends which suits your needs best. If it were me reading a whole file I would go for nextLine until I had all the file.
From the documentation for Scanner:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
From the documentation for next():
A complete token is preceded and followed by input that matches the delimiter pattern.
Just for another example of Scanner.next() and nextLine() is that like below :
nextLine() does not let user type while next() makes Scanner wait and read the input.
Scanner sc = new Scanner(System.in);
do {
System.out.println("The values on dice are :");
for(int i = 0; i < n; i++) {
System.out.println(ran.nextInt(6) + 1);
}
System.out.println("Continue : yes or no");
} while(sc.next().equals("yes"));
// while(sc.nextLine().equals("yes"));
Both functions are used to move to the next Scanner token.
The difference lies in how the scanner token is generated
next() generates scanner tokens using delimiter as White Space
nextLine() generates scanner tokens using delimiter as '\n' (i.e Enter
key presses)
A scanner breaks its input into tokens using a delimiter pattern, which is by default known the Whitespaces.
Next() uses to read a single word and when it gets a white space,it stops reading and the cursor back to its original position.
NextLine() while this one reads a whole word even when it meets a whitespace.the cursor stops when it finished reading and cursor backs to the end of the line.
so u don't need to use a delimeter when you want to read a full word as a sentence.you just need to use NextLine().
public static void main(String[] args) {
// TODO code application logic here
String str;
Scanner input = new Scanner( System.in );
str=input.nextLine();
System.out.println(str);
}
I also got a problem concerning a delimiter.
the question was all about inputs of
enter your name.
enter your age.
enter your email.
enter your address.
The problem
I finished successfully with name, age, and email.
When I came up with the address of two words having a whitespace (Harnet street) I just got the first one "harnet".
The solution
I used the delimiter for my scanner and went out successful.
Example
public static void main (String args[]){
//Initialize the Scanner this way so that it delimits input using a new line character.
Scanner s = new Scanner(System.in).useDelimiter("\n");
System.out.println("Enter Your Name: ");
String name = s.next();
System.out.println("Enter Your Age: ");
int age = s.nextInt();
System.out.println("Enter Your E-mail: ");
String email = s.next();
System.out.println("Enter Your Address: ");
String address = s.next();
System.out.println("Name: "+name);
System.out.println("Age: "+age);
System.out.println("E-mail: "+email);
System.out.println("Address: "+address);
}
The basic difference is next() is used for gettting the input till the delimiter is encountered(By default it is whitespace,but you can also change it) and return the token which you have entered.The cursor then remains on the Same line.Whereas in nextLine() it scans the input till we hit enter button and return the whole thing and places the cursor in the next line.
**
Scanner sc=new Scanner(System.in);
String s[]=new String[2];
for(int i=0;i<2;i++){
s[i]=sc.next();
}
for(int j=0;j<2;j++)
{
System.out.println("The string at position "+j+ " is "+s[j]);
}
**
Try running this code by giving Input as "Hello World".The scanner reads the input till 'o' and then a delimiter occurs.so s[0] will be "Hello" and cursor will be pointing to the next position after delimiter(that is 'W' in our case),and when s[1] is read it scans the "World" and return it to s[1] as the next complete token(by definition of Scanner).If we use nextLine() instead,it will read the "Hello World" fully and also more till we hit the enter button and store it in s[0].
We may give another string also by using nextLine(). I recommend you to try using this example and more and ask for any clarification.
The difference can be very clear with the code below and its output.
public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
List<String> arrayList2 = new ArrayList<>();
Scanner input = new Scanner(System.in);
String product = input.next();
while(!product.equalsIgnoreCase("q")) {
arrayList.add(product);
product = input.next();
}
System.out.println("You wrote the following products \n");
for (String naam : arrayList) {
System.out.println(naam);
}
product = input.nextLine();
System.out.println("Enter a product");
while (!product.equalsIgnoreCase("q")) {
arrayList2.add(product);
System.out.println("Enter a product");
product = input.nextLine();
}
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println("You wrote the following products \n");
for (String naam : arrayList2) {
System.out.println(naam);
}
}
Output:
Enter a product
aaa aaa
Enter a product
Enter a product
bb
Enter a product
ccc cccc ccccc
Enter a product
Enter a product
Enter a product
q
You wrote the following products
aaa
aaa
bb
ccc
cccc
ccccc
Enter a product
Enter a product
aaaa aaaa aaaa
Enter a product
bb
Enter a product
q
You wrote the following products
aaaa aaaa aaaa
bb
Quite clear that the default delimiter space is adding the products separated by space to the list when next is used, so each time space separated strings are entered on a line, they are different strings.
With nextLine, space has no significance and the whole line is one string.

Trouble with Scanner taking data from a command line using Java

I will admit, this is a school assignment... But I simply cannot figure out what I am doing wrong.
I have a hash table with an insert function. The following code is supposed to take a line of data from System.in in the format "Long String" (i.e. "32452 John"). The first token must be a Long for the ID number, and it must be followed by a String token for the name. When I run the program and I get to the portion where this must be executed (It is in a switch statement), I entered 'a' and hit enter. The command line immediately reads "Invalid value." (note: not VALUES, as that would mean it hit the nested if statement. It won't let me type in any data. Thank you in advance!
System.out.println("Enter ID and Name.");
//temp to take in the next line entered by the user
//inScan is the Scanner for System.in
temp = inScan.nextLine();
//Create Scanner for the line
Scanner tempScan = new Scanner(temp);
if(tempScan.hasNextLong()){
thisID = tempScan.nextLong();
if((tempScan.hasNext()) && (thisID>0)){
thisName = tempScan.next();
//The data will only be inserted if both segments of data are entered
myTable.insert(new Student(thisID, thisName));
}else{
System.out.println("Invalid values.");
}
}else{
System.out.println("Invalid value.");
}
Why do you need the second Scanner?
Example
String input = scanner.nextLine();
String[] tokens = input.split(" ");
Long id = Long.parseLong(tokens[0]);
String name = tokens[1];
And if you wanted to add your validation:
String input = scanner.nextLine();
if(input.contains(" ")) {
// You know there's a space in it.
String[] tokens = input.split(" ");
if(tokens.length == 2) {
// You know it's a value, followed by a space, followed by a value.
if(tokens[0].matches("[0-9]+")) {
// You know it only contains numbers.
Long id = Long.parseLong(tokens[0]);
}
}
}
I've not run it, but i guess your problem is that when you enter the text 'a' and hit enter, this line is false:
if(tempScan.hasNextLong()){
as you haven't entered a number. hence why it drops to the next block. If you enter something numerical first, i suspect your code with work. you probably need to add a 'while' loop around it, to run until it gets a number.
You already have a Scanner which reads from System.in, there's no need for another one. The second one you've made is a scanner for a String, which will never have a nextLong as it has nothing to scan after your String.
I won't write any code for you as this is homework, but stick to your original scanner when checking for user input instead.

A simple Java code that doesn't work well

The following simple code in Java behaves somewhat in a strange way that I can not understand.
final public class Main
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("\nHow many names? ");
int n = sc.nextInt();
String[] a = new String[n];
a[0] = sc.nextLine(); //This line serves no purpose at all. It's useless and should be removed.
for (int i=0; i<n; i++)
{
System.out.print("\nEnter the name:->");
a[i] = sc.nextLine(); //request for input only inside the loop.
}
for (int i=0; i<a.length; i++)
{
System.out.println(a[i]);
}
}
}
The above is working well with no problem at all and displays the number of names inputted into the array a[] on the console but when I remove the line a[0] = sc.nextLine(); //This line serves no purpose at all. It's useless and should be removed., it displays for number of users first. let's say 3. there is no problem but when the loop starts iterating, it will ask for the name and first time the message Enter the name:-> is displayed twice
and the output would be something like shown below.
How many names? 3
Enter the name:-> Don't allow to enter the name here.
Enter the name:->Tiger
Enter the name:->Pitter
Tiger
Pitter
Although I entered 3 for "How many names?", it allows only two names to enter. Why?
Note again that the code shown above is working well. The problem occurs only when the line specified with bold latters in the above paragraph is commented out.
When you use Scanner.nextInt(), it does not consume the new line (or other delimiter) itself so the next token returned will typically be an empty string. Thus, you need to follow it with a Scanner.nextLine(). You can discard the result instead of assigning it to a[0]:
int n = sc.nextInt();
sc.nextLine();
It's for this reason that I suggest always using nextLine (or BufferedReader.readLine()) and doing the parsing after using Integer.parseInt().
You are reading three lines. The problem you have is that nextInt() reads an int value, it doesn't read and consume the end of the line. (A common mistake)
You need the nextLine() after it to say that you want to ignore the rest of the line.
The nextInt call reads from input until the end of the int, but does not read the newline character after the int. So, the first iteration displays "enter the name", then calls nextLine() which reads the end of the line where you typed the number of players (an empty string). Then the second iteration starts and displays "enter the name", and nextLine() blocks until you type a newline character.

Categories