Unable to pass line to Scanner - java

Scanner kb=new Scanner(System.in);
System.out.println("\nDo you want to continue");
char answer=kb.next().charAt(0);
if(Character.toUpperCase(answer)=='Y') {
System.out.println("\nType any message to get Value");
String input=kb.nextLine();
class2 obj=new class2(input);
System.out.println("\n"+obj.getValue());
}
My program is not passing input to class2, it's just executing my method with empty input. I just tried every method, but none are working.

This will be solved by changing
char answer = kb.next().charAt(0);
to
char answer = kb.nextLine().charAt(0);
This is the solution because the next() method in Java does not advance the Scanner to the next line while nextLine() does.

You have two options:
1) make char answer=kb.nextLine().charAt(0);
2) make String input=kb.next();
Option 1: If you make it nextLine() it will consume the whole line and moves the cursor to next line. Thus there is no remaining string to be consumed.
Option 2: next() only consumes line till it finds a space and also it does not advances cursor to the next line. Thus for the first input if you type "yopo" the nextLine() will consume the remaining blank and you will not get anything.
In your case you should prefer the 1st option.

Related

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());

findWithinHorizon(".",0).charAt(0) Clarification

I'm having trouble understanding the source below:
myChar1 = myScanner.findWithinHorizon(".",0).charAt(0);
System.out.println(myChar1);
myChar2 = myScanner.findWithinHorizon(".",0).charAt(0);
System.out.print(myChar2);
I understand what it does, but I'm just having a bit of a trouble understanding how it works.
The actual prompting of the user for input is done at the first line right? but the real meaning of the first line is: "put the first char of input in myChar1". Then what happens? It seems the input still stays inside myScanner because when I use it in myChar2 I get the second char, but why? why not the first char? Does findWithinHorizon(".",0).charAt(0) deletes the char that is assigned to the variable?
And last question: if in the first line the program prompts the user for input why doesn't it do it again in the second line?
Also, a quick recap of the (".",0) would be helpful as well.
Perhaps the piece you are missing is that findWithinHorizon actually takes a regular expression as the String argument. In a regular expression, . matches any character (except a new line).
A call to findWithinHorizon(".", 0) simply finds the next character in the input and advances the Scanner past whatever was found.
So for example,
Scanner in = new Scanner("abc123");
for(;;) {
String found = in.findWithinHorizon(".", 0);
if(found == null) break;
System.out.println(found);
}
the output is:
a
b
c
1
2
3
The reason it does not prompt for input at the second line is that is the way Scanner and System.in work together. They will only block and prompt for input if there is no more existing input to consume. As a short example, try this out:
Scanner in = new Scanner(System.in);
while(true) {
System.out.println(in.findWithinHorizon(".", 0));
}
That will loop infinitely, repeating back whatever you input, character by character. It will only prompt for more when it's done with the prior input. On the first iteration, Scanner will call read on System.in which will block and wait for input. When the input runs out, read will block again.

System.out.println repeating itself

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.

How to test for blank line with Java Scanner?

I am expecting input with the scanner until there is nothing (i.e. when user enters a blank line). How do I achieve this?
I tried:
while (scanner.hasNext()) {
// process input
}
But that will get me stuck in the loop
Here's a way:
Scanner keyboard = new Scanner(System.in);
String line = null;
while(!(line = keyboard.nextLine()).isEmpty()) {
String[] values = line.split("\\s+");
System.out.print("entered: " + Arrays.toString(values) + "\n");
}
System.out.print("Bye!");
From http://www.java-made-easy.com/java-scanner-help.html:
Q: What happens if I scan a blank line with Java's Scanner?
A: It depends. If you're using nextLine(), a blank line will be read
in as an empty String. This means that if you were to store the blank
line in a String variable, the variable would hold "". It will NOT
store " " or however many spaces were placed. If you're using next(),
then it will not read blank lines at all. They are completely skipped.
My guess is that nextLine() will still trigger on a blank line, since technically the Scanner will have the empty String "". So, you could check if s.nextLine().equals("")
The problem with the suggestions to use scanner.nextLine() is that it actually returns the next line as a String. That means that any text that is there gets consumed. If you are interested in scanning the contents of that line… well, too bad! You would have to parse the contents of the returned String yourself.
A better way would be to use
while (scanner.findInLine("(?=\\S)") != null) {
// Process the line here…
…
// After processing this line, advance to the next line (unless at EOF)
if (scanner.hasNextLine()) {
scanner.nextLine();
} else {
break;
}
}
Since (?=\S) is a zero-width lookahead assertion, it will never consume any input. If it finds any non-whitespace text in the current line, it will execute the loop body.
You could omit the else break; if you are certain that the loop body will have consumed all non-whitespace text in that line already.
Scanner key = new Scanner(new File("data.txt"));
String data = "";
while(key.hasNextLine()){
String nextLine = key.nextLine();
data += nextLine.equals("") ? "\n" :nextLine;
}
System.out.println(data);
AlexFZ is right, scanner.hasNext() will always be true and loop doesn't end, because there is always string input even though it is empty "".
I had a same problem and i solved it like this:
do{
// process input
}while(line.length()!=0);
I think do-while will fit here better becasue you have to evaluate input after user has entered it.

How do I keep a Scanner from throwing exceptions when the wrong type is entered?

Here's some sample code:
import java.util.Scanner;
class In
{
public static void main (String[]arg)
{
Scanner in = new Scanner (System.in) ;
System.out.println ("how many are invading?") ;
int a = in.nextInt() ;
System.out.println (a) ;
}
}
If I run the program and give it an int like 4, then everything goes fine.
On the other hand, if I answer too many it doesn't laugh at my funny joke. Instead I get this(as expected):
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at In.main(In.java:9)
Is there a way to make it ignore entries that aren't ints or re prompt with "How many are invading?" I'd like to know how to do both of these.
You can use one of the many hasNext* methods that Scanner has for pre-validation.
if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}
This prevents InputMismatchException from even being thrown, because you always make sure that it WILL match before you read it.
java.util.Scanner API
boolean hasNextInt(): Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.
String nextLine(): Advances this scanner past the current line and returns the input that was skipped.
Do keep in mind the sections in bold. hasNextInt() doesn't advance past any input. If it returns true, you can advance the scanner by calling nextInt(), which will not throw an InputMismatchException.
If it returns false, then you need to skip past the "garbage". The easiest way to do this is just by calling nextLine(), probably twice but at least once.
Why you may need to do nextLine() twice is the following: suppose this is the input entered:
42[enter]
too many![enter]
0[enter]
Let's say the scanner is at the beginning of that input.
hasNextInt() is true, nextInt() returns 42; scanner is now at just before the first [enter].
hasNextInt() is false, nextLine() returns an empty string, a second nextLine() returns "too many!"; scanner is now at just after the second [enter].
hasNextInt() is true, nextInt() returns 0; scanner is now at just before the third [enter].
Here's an example of putting some of these things together. You can experiment with it to study how Scanner works.
Scanner in = new Scanner (System.in) ;
System.out.println("Age?");
while (!in.hasNextInt()) {
in.next(); // What happens if you use nextLine() instead?
}
int age = in.nextInt();
in.nextLine(); // What happens if you remove this statement?
System.out.println("Name?");
String name = in.nextLine();
System.out.format("[%s] is %d years old", name, age);
Let's say the input is:
He is probably close to 100 now...[enter]
Elvis, of course[enter]
Then the last line of the output is:
[Elvis, of course] is 100 years old
In general I really, really dislike using the same library call for both reading and parsing. Language libraries seem to be very inflexible and often just can't be bent to your will.
The first step that pulls data from System.in should not be able to fail, so have it read it as a string into a variable, then convert that string variable to an int. If the conversion fails, great--print your error and continue.
When you wrap your stream with something that can throw an exception, it gets kind of confusing just what state the whole mess leaves your stream in.
It's always a benefit to have your application throw an error when an error occurs opposed to ways to keep it from happening.
One alternative is to wrap the code inside a try {...} catch {...} block for InputMismatchException.
You might also want to wrap the code inside a while loop to have the Scanner keep prompting until a specific condition is met.

Categories