trouble with the scanner and int (nextLine and next) [duplicate] - java

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 19 days ago.
Ive been having some trouble with this assignment, its supposed to be kind of like a supermarket thing. I am new in java, the only import we are allowed to have if the scanner one.
The first time we record a customer and their items it works fine, it let me choose as many items as i want and of already existing in the array and everything runs smoothly - it goes on to ask if there´s any coupons and then it "prints" the receipt - the problem is the second customer - it all runs smoothly until this code (the one i´ll show below) it only lets me choose one product and the quantity and then it kind of moves to the next thing (ask for coupons and so on) and the third time it only let me choose the product - so i believe the problem is with the int.nextLine or something - i have looked at other questions and TRIED addind a nextLine or just next but it keeps happening so it might be the do while... i am not sure, i am new in java and in coding really - i will appreciate any kind of suggestion or input on it really.
do{
System.out.println("WHICH ITEM WOULD YOU LIKE TO BUY");
int CodeItem=input.nextInt();
//the array has max 20 items
if(CodeItem<=20 && CodeItem>=1){
if(item[CodeItem-1]!=("null") && price[CodeItem-1]!=0.0)
{
System.out.println("How many of:"+item[CodeItem-1]);
int CANT=input.nextInt();
LOCALamount[CodeItem-1]+=CANT;
GLOBALamount[CodeItem-1]+=CANT;
//the boolean ending is declared as true at the start of the code
}
else
{
System.out.println("****not valid****");
ending=false;
}}else
{
System.out.println("****not valid****");
ending=false;
}
}while(ending);

The issue is likely with the use of input.nextInt() and input.nextLine() in the same loop. The input.nextInt() method reads the next integer but does not consume the newline character that follows. This means the first call to input.nextLine() will immediately return an empty line, causing the loop to terminate.
One possible solution is to use input.nextLine() after the call to input.nextInt() and then parse it to an integer using the Integer.parseInt() method. This will ensure that the newline character is consumed, allowing the loop to continue as expected.
Here's an updated version of the code:
do {
System.out.println("WHICH ITEM WOULD YOU LIKE TO BUY");
int codeItem = Integer.parseInt(input.nextLine());
if (codeItem <= 20 && codeItem >= 1) {
if (item[codeItem - 1] != ("null") && price[codeItem - 1] != 0.0) {
System.out.println("How many of:" + item[codeItem - 1]);
int cant = Integer.parseInt(input.nextLine());
LOCALamount[codeItem - 1] += cant;
GLOBALamount[codeItem - 1] += cant;
} else {
System.out.println("****not valid****");
ending = false;
}
} else {
System.out.println("****not valid****");
ending = false;
}
} while (ending);

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

Using delimiters to split an equation and run it

So I am doing a project for a class of mine and it involves the use of delimiters and other scanner methods. However I've been doing a lot of research and the book we have does not clearly explain as to how it works. So after several headaches and trying to understand I figured I'd ask here (EDIT: This is something somewhat similar I found [relating to delimiters and splitting number sequences] to what my teacher was asking me and thought it would be adequate to ask it here. So before I get accused of doing my homework on here I wanted to clarify)
Here's what I have typed so far:
import java.io.*;
import java.util.*;
public class addUp
{
public static void main(String args[])
{
Scanner kb = new Scanner(System.in);
System.out.print("Enter something like 8 + 33 + 1345 - 137 : ");
String s = kb.nextLine( );
Scanner sc = new Scanner(s);
/* sc.useDelimiter("\\s*"); With some help and research I found
out that the \\s* actually causes every character to be split
apart. so 33 is 3 3 */
int sum = sc.nextInt();
while(sc.hasNextInt( ))
{
String operator = sc.next();
int value = sc.nextInt();
if(operator.equals("-"))
{
sum = sum - value;
}
else if(operator.equals("+"))
{
sum = sum + value;
}
}
System.out.println("Sum is: " + sum);
}
}
And my last attempt got me a weird output:
----jGRASP exec: java addUp
Enter something like 8 + 33 + 1345 - 137 : 8 + 33 + 1345 - 137
Sum is: 8
----jGRASP: operation complete.
Now I don't know a ton and I'm sure if I came in with something more complicated than the progress of what we've been through would not be appreciated (since I know I've seen some people answer other questions that is way over my understanding). So keep it dumbed down for me if you can XD. Thanks.
The problem with your code at the moment is that your while loop is checking for while(sc.hasNextInt( )), but it's expecting an operator. Change that to while(sc.hasNext() and you should be ok.
Additionally, when facing problems like this, try running your code in a debugger and stepping through it. You'd see pretty quickly that it didn't enter into the while loop and that would help you diagnose the problem. If you don't have access to a debugger, just put in some System.out.println() statements.
UPDATE
So, I ran your code in a debugger (after changing the while loop as I described), and the first thing I noticed was that the first call to sc.nextInt() returns 3, not 33, because of the reason H L explained. Having removed the call to setDelimeter, the code runs fine. It should now look like:
import java.io.*;
import java.util.*;
public class addUp
{
public static void main(String args[])
{
Scanner kb = new Scanner(System.in);
System.out.print("Enter something like 8 + 33 + 1345 - 137 : ");
String s = kb.nextLine( );
Scanner sc = new Scanner(s);
//sc.useDelimiter("\\s*"); <-- don't do this
int sum = sc.nextInt();
while(sc.hasNext( )) // <-- not hasNextInt
{
String operator = sc.next();
int value = sc.nextInt();
if(operator.equals("-"))
{
sum = sum - value;
}
else if(operator.equals("+"))
{
sum = sum + value;
}
}
System.out.println("Sum is: " + sum);
}
}
And outputs:
Enter something like 8 + 33 + 1345 - 137 : 8 + 33 + 1345 - 137
Sum is: 1249
Again, you should have spotted this if you stepped through your code in a debugger (Eclipse, IntelliJ, NetBeans, jdb, etc).
There are multiple issues with your code:
You call the next() and nextInt() methods multiple times within the while loop which consumes too much of our input.
The sum is initialized to 0 and the very first operand is omitted.
Only the last else block is executed because you compare strings with characters (single quotes instead of double quotes) which always evaluates to false.
Code:
// WRONG: sc.useDelimiter("\\s*");
int sum = sc.nextInt(); // consume the first token, must be an integer
while (sc.hasNext()) { // as long as there are more tokes, do the following
String operator = sc.next(); // read next token, must be a + or - sign
int operand = sc.nextInt(); // read next token, must be an integer again
// depending on the arithmetic operator we update the sum variable
if (operator.equals("-")) {
sum = sum - operand;
} else if (operator.equals("+")) {
sum = sum + operand;
} else {
// if the operator variable contains something else than a + or - sign
// we throw an exception. In general this is the preferred way to avoid
// that the software changes into an undefined state.
throw new RuntimeException("Unknown operator: " + operator);
}
}
System.out.println("Sum is: " + sum);
First Problem (Apparently corrected in an edit to the quesiton)
You call sc.next() in every if statement. Call it once, and then use the value when you need it. If you keep calling it, you'll keep eating your input!
String op = sc.next();
if (op.equals('-') {}
else if (op.equals('+') {}
else {}
Second Problem
You never initialize sum to the first number. You skip the first number completely! Start off like this to make sure you consume the first int before you consume the first operator.
int sum = sc.nextInt();
Third Problem
hasNextInt() only returns true if the next token is an int. It returns false if the next token is an operator like "+" or "-". Change your while to loop on hasNext().
The last fix may cause you to consume a "/n" or some other line seperator nonsense on your last iteration of the loop. as it stands, it looks like this will only cause you to print the sum twice. That seems like something you should be able to solve on your own.
Rather than making me edit my answer four MORE times, try to do this on paper, going in circles for the while loop. Consume an int. Consume an operator. Consume an int. Consume an operator. Consume an int. If you break that order, your logic isn't in the right order. Know the logic before you even try to write code.
Go read the Javadoc for Scanner to see what each method you are calling actually does. Learn about Streams in Java so you understand how they work.

Java Scanner doesn't work in Processing

For an assignment I have due, my group and I were asked to code an educational/interactive game, and we decided on a basic maths one.
To get the users answers, we decided to use Java Scanner and put this line of code at the top of all the code we have;
java.util.Scanner
One of the loops that use this is the page with the questions on it, the loop looking something like this;
scoreCount = 0;
for (questions = 0; questions < 5;) {
//get the user's answer
userAnswer[questions] = input.nextInt();
//text box for users answer
if (userAnswer[questions] == compAnswer) {
//put tick next to answer
//add one to score
scoreCount = scoreCount + 1;
} else if (userAnswer[questions] != compAnswer) {
//put cross next to answer
}
//go to next question
questions++ ;
}
I'm working through all the errors that were thrown up and every time i don't have java.util.Scanner commented out Processing throws us the errors unexpected token: and then either class or void, which i don't get, but when java.util.Scanner is commented out, the classes and voids all work and the .input.nextInt() isn't recognised.
I am new to Java programming and Processing, any help at all would be greatly appreciated
EDIT
i think this is the link which lets you see my code, it's called Test;
https://github.com/MeganSime/Week8DataVis
you have to check if scanner has next int (token)
Scanner input = new Scanner(System.in);
.
.
if(input.hasNextInt()) { // or hasNext()
userAnswer[questions] = input.nextInt();
}
You're probably inserting a non int value where the scanner expects that. You should do something like that:
if(input.hasNextInt()) {
userAnswer[questions] = input.nextInt();
} else {
scan.next(); //consume any non-int value like ":"
}

try statement not being used on second illiteration of loop [duplicate]

This question already has answers here:
try/catch with InputMismatchException creates infinite loop [duplicate]
(7 answers)
Closed 7 years ago.
I am making a method in order to get how many numbers the user wants to sum together. aka if they want to sum the numbers 1 2 and 3. they would want to sum 3 numbers together. So when i ask them how many they want to sum together, I use a try - catch in order to catch if they enter a decimal place. Because you cant add together 3.5 numbers you can add 3 numbers or 4. problem is if the user enters a decimal, the program will infinite loop run everything but what is in the try statement. How can i fix this?
Here is the code for the method:
private static int requestMaxInputForFloat(Scanner scanner){
boolean appropriateAnswer = true; // assume appropriate catch not appropriate to loop again
int howManyInputs = 1000000; // hold value to return how many inputs. if this value we will not run.
//request an appropriate number of inputs until appropriate answer = true;
do
{
appropriateAnswer = true; //if looped again reset value to true
try{
System.out.print("How many decimal place numbers would you like to sum? ");
howManyInputs = scanner.nextInt();
}catch(Exception e){
System.out.println("Sorry but you can only request to average a whole number set of data.\nTry Again.");
appropriateAnswer = false;
}//end of try-catch
if (howManyInputs <= 0) //invalid answer
{
System.out.println("Sorry but " + howManyInputs + " is equal to or below 0. Please try again.");
}else{
appropriateAnswer = false;
}
}while(!appropriateAnswer);//end of while loop
return howManyInputs; //return the value
}// end of getMaxInput
Add scanner.nextLine(); in the catch block. I think the problem is that if nextInt() gets an error, the scanner's "pointer" is still pointing at a bad character, and if you just try nextInt() again, it will try to scan the same bad character over again. You have to do something to make the scanner skip over it. Here, you want to just throw away whatever the user typed in, so nextLine(), which skips over the entire remainder of the input line, is the most appropriate.
One other thing: I'd change
if (howManyInputs <= 0) //invalid answer
to
if (appropriateAnswer && howManyInputs <= 0) //invalid answer
Otherwise, if the user types in -1, then the loop will go back and howManyInputs will still be -1; then if the user types 3.5, you'll get the exception but you'll get a second error message because howManyInputs is still -1 left over from the previous loop. You don't need to test howManyInputs if you already know there was an input error.

For or While loop skipping an input [duplicate]

This question already exists:
Closed 10 years ago.
Possible Duplicate:
Scanner issue when using nextLine after nextInt
I am creating a client program that needs to read both a String and an integer from my server. Depending on what integer it receives it adds some labels to the GUI. So far, my program reads the integer but skips the String. The following output is the output of my program when I try to write the integers to the program:
Server writes: 1
Server writes: 1
System prints: 1
System prints: j1
System prints: Name
The problem is that I am unable to write a String because it skips the String. How can I avoid this problem (note that I have also tried a for loop)
My code is as following:
int times = client.reciveCommando();
int o = 0;
System.out.println(times);
while (o != times) {
int j = client.reciveCommando();
System.out.println("j"+ j);
String name = client.reciveString();
System.out.println("Name " +name);
createUser(j, name);
o++;
}
The createUser method:
private void createUser(int j, String reciveChat) {
if (j == 1) {
chatPerson1.setVisible(true);
lbl_Chatperson1_userName.setVisible(true);
lbl_Chatperson1_userName.setText(reciveChat);
} else if (j == 2) {
lbl_chatPerson2.setVisible(true);
lbl_userName2.setVisible(true);
lbl_userName2.setText(reciveChat);
} else {
chatPerson3.setVisible(true);
lbl_userName3.setVisible(true);
lbl_userName3.setText(reciveChat);
}
}
The client.reciveCommando method:
public int reciveCommando() throws IOException{
Integer i = input.nextInt();
return i;
}
The client.reciveString method:
public String reciveString(){
String x = input.nextLine();
return x;
}
Hope someone is able to help me with this :)
Thank you in advance.
I don't see anywhere in the loop code where you are incrementing o or changing the value of times. So either the loop is being skipped altogether (ie: times = 0) or some other place in the code is modifying either the loop variable (o) or the loop condition (times) - very bad coding in either case.
Your loop variable/increment rules should be very clear in reading the loop and easily discernible what the start/stop conditions are without needing to read other methods/etc which may modify the values during loop iteration.
My immediate guess is that times = 0, or you would be in an endless loop.
i found the solution to my question it turned out to be quite simple!
first of all let me explain what i ment.
When i my program ran the while loop it basicly skipped the line where it should have recived an input from the server. i found that the reason it did that was that the input.nextLine(); was empty which makes sence when you read the api for input.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.
Returns:
the line that was skipped
since the line that i tried to get was an empty line it would skip and set name to " ".
here is the full complete code for my program and it currently works:
The while loop:
while (o != times) {
int j = client.reciveCommando();
System.out.println("j"+ j);
String name = client.reciveString();
System.out.println("Name " +name);
createUser(j, name);
o++;
}
The client.reciveString();
public String reciveString(){
String x = input.next();
return x;
}
The createUser();
private void createUser(int j, String reciveChat) {
if (j == 1) {
chatPerson1.setVisible(true);
lbl_Chatperson1_userName.setVisible(true);
lbl_Chatperson1_userName.setText(reciveChat);
}else if (j == 2) {
lbl_chatPerson2.setVisible(true);
lbl_userName2.setVisible(true);
lbl_userName2.setText(reciveChat);
}else if (j == 3){
chatPerson3.setVisible(true);
lbl_userName3.setVisible(true);
lbl_userName3.setText(reciveChat);}
Thank you for all of your responses and i will be sure to vote you up :)

Categories