So I've just started java with a tiny bit of experience from a few other languages. I tried to make this basic calculator and had a lot of problems but managed to resolve most of them. The last thing that I can't seem to understand is a randomly triggered "This is an invalid input", every time my program runs once. "..." refers to irrelevant code. Everything else seems to work fine. Thanks in advance!
import java.util.Scanner;
public class Calc {
...
System.out.println("Would you like to use the calculator?(Y/N)");
while(use){
String usage=in.nextLine().toLowerCase();
if(usage.equals("n")){use=false;}
//input
//operations
else if(usage.equals("y")){
...(calculator code)
System.out.println("Continue use? (Y/N)");
}
else {System.out.println("That is not a valid input");}
}
}
}
After running my code a few times, my output is
Would you like to use the calculator?(Y/N)
Y
Please input an operation: +,-,*,/,%, ^, or root
+
Calculator: Please input your first number.
1
Now enter your second number.
2
Calculating
3.0
Continue use? (Y/N)
That is not a valid input <-- right there is the confusing part, why is that triggered?
Y
Please input an operation: +,-,*,/,%, ^, or root
Full code is on pastebin, if you somehow need it. http://pastebin.com/Qee2Hxe3
I checked the full code, and right before the loop first reiterates, there is a call to in.nextDouble(), this method reads a double but does not consume the line end, which makes the next in.readLine() return \n immidiately and the succeeding test fails.
A simple solution is to manually consume the line-end:
System.out.println(ans);
System.out.println("Continue use? (Y/N)");
in.nextLine();
I tested your code and found that a solution is to declare your scanner inside your while loop, like so:
while (use) {
Scanner in = new Scanner(System.in);
String usage = in.nextLine().toLowerCase();
Here's what the problem is: first, you are entering your while loop, and usage is set equal to in.nextLine(). Since there is no next line, it waits for you to enter one. You enter yes, after which you enter your formula. Then it returns the answer, and goes back to the top of the while loop. Once again, usage is set to equal in.nextLine, but there is already a next line (a blank one) and so usage is set to equal an empty String ("") which is neither "y" or "n". Then it immediately goes to the "else" option at the end and prints the "invalid" message.
Re-assigning your scanner through each iteration of your while loop fixes this problem.
The last input you read in your code when calculating is this:
num2=in.nextDouble();
This reads the next characters and convert it to a double. However when you input your number, you also hit enter.
This means that after the double is read, there is still a newline character left in the input buffer.
As the code goes back to the String usage=in.nextLine().toLowerCase(); , you will now read this newline.
You could just ignore empty input, by e.g. doing
String usage=in.nextLine().toLowerCase().trim();
if (usage.isEmpty()) {
continue;
}
Related
so, i am looking to write code which firstly asks for user input in order to run the desired operation, this element of my code is working fine, but after selecting one of the options from the first menu i am asking the user for a second string input which i would like to turn to both lower and uppercase, but instead of letting me enter an input, the program just goes back to the original screen showing all options.
this is my code asking for a string input that isnt working:
else if(choice1==1)
{
System.out.println("================================="+"\n"+"You have chosen to convert a given string to upper case and lowercase, please enter your string: "+"\n");
choice2 = sc.nextLine();
System.out.println("Your lowercase string: "+choice2.toLowerCase()+"\n"+"Your uppercase string: "+choice2.toUpperCase);
}
Cheers for the help guys!!
You need to consume the end of line character:
choice1 = sc.nextInt();
sc.nextLine(); // consume the end of line
// Now your program continues as before.
// Probably you have an 'if' here, I don't know, you
// haven't shown it
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 11 months ago.
it seems like the code is skipping the first "Next.Line()" and is going straight to the second one. here is what happens when it runs. Thanks
import java.util.*;
public class PrintWriter {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scn = new Scanner(System.in);
System.out.println("Would you like to enter some names?");
String response = scn.next();
int namecount = 1;
String name;
if (response.equals("yes") || response.equals("Yes") || response.equals("Yes"))
{
System.out.println("How many names would you like to enter?");
for (int nameresponse = scn.nextInt(); namecount <= nameresponse; ++namecount)
{
System.out.println("Please enter the name of name #" + namecount );
name = scn.nextLine();
}
}
}
}
nextLine() does exactly what its javadoc says it does, which is not what you think it does. Scanner is best used as follows:
Never call nextLine - only call all the other methods (next(), nextInt(), etcetera).
Only call nextLine, never call all the other methods.
Obviously, given that reading integers is nice sometimes, the first choice is the superior one.
For keyboard input, which is what Scanner is usually used for, the best way to use it is to set it up to actually do what most people think it does - inputs are entered by the user and the user completes any input by hitting the enter key.
To do so, immediately after new Scanner, you write:
scanner.useDelimiter("\\R");
This is java-ese for: "input is delimited by newline symbols" and works on any platform. Now, to read integers, run .nextInt(). To read text, run .next() (which reads an entire line's worth). There is no way to read 'one word' - that rarely comes up, fortunately. Upside: You avoid the weird interaction between nextLine and all the other next methods, and you the user can now enter blank input (.next() will return an empty string if the user just hits enter, whereas that just doesn't work at all if you use scanner in its default configuration).
But why?
scanner 'tokenizes' the input by scanning for the delimiter and returning the stuff in between the delimiter. Out of the box, the delimiter is configured to be '1 or more whitespace symbols'. This means next() will read one word, and it also means it is impossible read zero-length input (because just hitting enter is simply adding more and more whitespace, you're just continuing to type more of the same delimiter). Neither is convenient, hence, we don't want that.
Whenever you 'consume' a token (any of the next() methods does this), the 'cursor' is now at the end of the token and at the start of the delimiter that followed it: If the user entered a name and then hit enter, we're at the start of that enter press, right before it.
You then call nextLine() which is a completely different feature that entirely ignores this 'token' and 'delimiter' business, and simply returns everything until a newline symbol. Given that the very next symbol is a newline symbol, you get an empty string back.
One very common but bad solution is to just call scanner.nextLine(), igoring the result, after each invocation of any non-nextLine next method. However, if you do that, everything goes in a handbasket when the user hits that biggest of keys on their keyboard - the spacebar. So don't do that, call .useDelimiter("\\R"), and forget about .nextLine().
you need to use scn.nextLine() instead of scn.next . .next only reads one word until space appears and terminate to next step whereas nextLine considers the complete line.
I have never encountered a problem of this sort before, but three of my latest projects are all having this same problem where, for some reason, Java is skipping over the user's input. Whatever help is offered would be much appreciated!
Note: Just to give some background for this problem, the program is supposed to run a game in a do-while loop. After the first round is complete, the purpose of these lines of code is to allow the user to play more rounds of the game. It stores the user's input in a String and then takes the first character. If the character is 'y' or 'Y', then another round will begin. If the character is not either 'y' or 'Y', the program will end.
int iterations = 0;
do{
System.out.println(result + " Would you like to play again:");
String strHolder = keyboard.nextLine();
char repeatOption = strHolder.charAt(0);
iterations++;
} while(repeatOption == 'y' || repeatOption == 'Y');
So the game itself runs fine, but when I get to this part of the program that asks the user if he would like to play again, this happens in my terminal:
Would you like to play again:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
So, as you can see, the program skips over user input, and there is no "first character" to set the char repeatOption. Again, thanks for taking the time to read this problem, and any support would be much appreciated.
Scanner buffer was not empty (probably new line char was there) and when your programme was trying to get input from user, scanner was insntly getting value from buffer and nextLine() method did not return anything.
Possible solutions:
change nextLine() to other method that not consume the new line char (\n)
flush the buffer before getting value from user
I need explanation about how does scanner's hasNextInt() works. In next example:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
boolean foo = sc.hasNextBoolean();
System.out.println(sc.nextLine());
}
when program gets to hasNextBoolean(), it waits for my input. Then I press Enter for newline and type true and press Enter again,so the buffer looks like this: [ \n true \n ].
Now the pointer is on word true, and so foo becomes true. But then, the pointer should still be hanging on true, and when next line comes, program should print true, but what happens is that it just prints newline. Why is that case, may I ask?
On the other hand, doing same thing but using nextInt(), works the way that i expected:
public static void main(String[] args) {
Scanner skener = new Scanner(System.in);
try{
int stagod = skener.nextInt();}
catch(Exception e){
System.out.println(skener.nextLine());}
}
Here when program come to skener.nextInt(), I press Enter then type A then press Enter, so the buffer looks like this: [ \n A \n ].
And now, after catching the exception, pointer stays on A and System.out.println(skener.nextLine()); prints A.
sc.hasNextBoolean() is working just fine. The problem is that you failed to account for sc.hasNextBoolean() not advancing past the input that it reads.
sc.hasNextBoolean() reads the input but does not advance past it. So after that call, the input buffer would be "\n", one line. sc.nextLine() DOES advance the scanner past the input after reading it. But in this case, it also waits for the user to enter another line. For you, that would be "true\n" which would make the buffer "\ntrue\n" as expected. But the buffer is 2 lines long. sc.nextLine() only reads one line (the next line). That next line is "\n", it's just a line break. After the System.out.println() call. There is still data in the buffer, which is now "true\n". There's still one line left.
You will find that if you add one more System.out.println(sc.nextLine()), your code will work as expected.
The reason why sc.nextInt() works is because it DOES advance the scanner past the input it reads. It waits for a line of input and then reads it. At this point, the buffer is "\n". But then it also advances past that input that it just read, so the buffer is now empty. The next time you call sc.nextLine(), the scanner is at the position before the line you type, rather than a line behind. So you only need one call to sc.nextLine().
The key to your problem is not that the Scanner methods aren't working as expected. Your problem is simply that your failed to consider that one minor, but crucial, detail about the Scanner.hasNextBoolean() method. There's little things in the documentation like that which can make or break a program. Next time, just remember to read the full documentation of the method you are using before you implement it.
What I am trying to do is have the user enter a lot of numbers and then hit enter, and then store all those numbers onto a stack at once. My thought was to use a loop to go through all the numbers and push them onto the stack like so:
Stack<Integer> mainBin = new Stack<Integer>();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
mainBin.push(scanner.nextInt());
}
However, even after I press enter many times without entering anything new, it still stays in the loop. Any suggestions?
Scanner.hasNextInt() skips over whitespace to find the next token. So it reads and skips over all your Enter presses. Then it waits for more input, because there may be more input coming.
In a Linux terminal, you can press Ctrl-D (maybe Cmd-D on OS X?) to send an end-of-file marker, which tells the application that there is no more input coming (this should be done at the start of a line). This answer suggests that Ctrl-Z is the equivalent in Windows' command prompt.
Alternatively, you could have some special input that your application reads. #phatfingers commented that you could specify the number of values to read as the very first input. You could also have a special value to signify the end (0 or -1 are common choices, based on the application's needs), or maybe even use a non-numeric token like "end".
Your example uses scanner.hasNext(). Use scanner.hasNextInt() instead.