How to prevent string from printing repeatedly in while loop? - java

I'm currently working on some exercises given to me by my teacher. These are for the holidays so I won't be able to ask for help there.
I have this piece of code which creates a multiplication table from an integer defined by the user, ranging from a minimum and maximum also defined by the user.
Before setting any of my variables to the next integer in my Scanner, I do a check to see if the Scanner actually has an integer. This works fine but I don't want it to print out the error message a billion times.
Any tips/tricks or other special ways of getting around this?
public class MultiplicationTable
{
private int intervalMin;
private int intervalMax;
private int multiplier;
private int result;
private Scanner sc;
public MultiplicationTable()
{
multiplier = 0;
intervalMin = 0;
sc = new Scanner(System.in);
while (multiplier == 0)
{
System.out.println("Please enter the integer you wish to show the table for");
if (sc.hasNextInt())
{
multiplier = sc.nextInt();
}
else
{
System.out.println("Input is not an integer\n");
}
}
while (intervalMin == 0)
{
System.out.println("\nPlease enter the integer defining the start of the table");
if (sc.hasNextInt())
{
intervalMin = sc.nextInt();
}
else
{
System.out.println("Input is 0 or not an integer\n");
}
}
while (intervalMax == 0)
{
System.out.println("\nPlease enter the integer defining the end of the table");
if (sc.hasNextInt())
{
int i = sc.nextInt();
if (i > intervalMin)
{
intervalMax = i;
}
else
{
System.out.println("\nEnd integer must be greater than start integer");
}
}
else
{
System.out.println("Input is 0 or not an integer");
}
}
System.out.println("\nTable for integer " + multiplier + " from " + intervalMin + " to " + intervalMax + "\n");
for (int i = intervalMin; i <= intervalMax; i++)
{
result = i * multiplier;
System.out.println(i + " * " + multiplier + " = " + result);
}
}
}

You didn't consume what user entered into the scanner buffer, that's why sc.hasNextInt() keeps getting executed without waiting for the next user input.
The solution is to add sc.nextLine() after the if condition.
For example:
boolean gotInteger = false;
while (!gotInteger) {
System.out.println("Please enter the integer you wish to show the table for");
if (sc.hasNextInt()) {
multiplier = sc.nextInt();
gotInteger = true;
} else {
System.out.println("Input is not an integer\n");
}
sc.nextLine();
}

Pleas try this, just wrap all your code inside try catch:
try {
while (intervalMax == 0) {
System . out . println("\nPlease enter the integer defining the end of the table");
if (sc . hasNextInt()) {
int i = sc . nextInt();
if (i > intervalMin) {
intervalMax = i;
} else {
throw new Exception("\nEnd integer must be greater than start integer");
}
}
}
} catch (Exception e) {
System . out . println(e . getMessage());
}

Related

if else condition is not executed properly

I have a condition where if the user inputs a negative number or a number which is more than 100, or a string, an error message should be printed "That wasn't a valid percentage, I need a number between 0-100. Try again." and ask the user to reenter a valid number. and if the user decided to just enter, all the input should be calculated and printed the average amount.
public static void main(String[ ] args) {
int count = 0; //count to stop loop
double[ ] aGrade = new double[SIZE];
String input = new String("");
Scanner scan = new Scanner(System.in);
double total = 0;
int gTotal = aGrade.length;
boolean exit = false;
while ((count < SIZE) && (!exit)) {
System.out.print("Enter number " + (count + 1) + ": " + "\n");
try {
input = scan.nextLine();
if (Double.parseDouble(input) > 0 && Double.parseDouble(input) < 100) {
aGrade[count] = Double.parseDouble(input); //put into the array
count++; //only increment count if success
} else
System.out.println("That wasn't a valid percentage,"
+ " I need a number between 0-100. Try again.");
} catch (NumberFormatException nfe) {
exit = true; //exit loop
}
}
System.out.println("number of grades entered: " + count + "\n");
for (int i = 0; i < count; i++) {
// print entered grade
System.out.println("grade " + (i + 1) + ": " + aGrade[i]);
}
for (int i = 0; i < count; i++) {
total += aGrade[i];
}
// calculate and print the average
System.out.println("\n" + "Average grade: " + total /count);
But when I run my code, if I input letters, it won't allow the user to reinput value but prints whatever is calculated. I think it is in my if-else statement, but I am not sure how
When we try to convert String to Double it will throw java.lang.NumberFormatException. So whenever you enter String or char at that time instead of else it will go to catch block. As per your code else block only executed when user enter negative number or grater then 100 number.
I updated your code. Please review it.
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
int count = 0; // count to stop loop
double[] aGrade = new double[3];
String input = new String("");
Scanner scan = new Scanner(System.in);
double total = 0;
int gTotal = aGrade.length;
boolean exit = false;
while ((count < 3) && (!exit)) {
System.out.print("Enter number " + (count + 1) + ": " + "\n");
try {
input = scan.nextLine();
if (Double.parseDouble(input) > 0 && Double.parseDouble(input) < 100) {
aGrade[count] = Double.parseDouble(input); // put into the array
count++; // only increment count if success
} else
System.out
.println("That wasn't a valid percentage," + " I need a number between 0-100. Try again.");
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
exit = true; // exit loop
}
}
if (!exit) {
System.out.println("number of grades entered: " + count + "\n");
for (int i = 0; i < count; i++) {
// print entered grade
System.out.println("grade " + (i + 1) + ": " + aGrade[i]);
}
for (int i = 0; i < count; i++) {
total += aGrade[i];
}
// calculate and print the average
System.out.println("\n" + "Average grade: " + total / count);
}else {
System.out
.println("That wasn't a valid percentage," + " I need a number between 0-100. Try again.");
}
}
}
If you type letter as an input, you will never end up in your else part of the if statement since code inside if throws an exception and you are then inside catch part. Also, you wrote inside catch part, when NumberFormatException happens(when you enter letter instead of number), set exit to true and that is the reason why program don't let you type again after you input letter. Fix those things and it will work. Also, take a look at how to debug your program, learn that skill, it will help you to solve this kind of problems in the future.
Try something like this:
boolean ok = false;
try {
input = scan.nextLine();
if ("".equals(input)) {
ok = true;
exit = true;
} else if (Double.parseDouble(input) >= 0 && Double.parseDouble(input) <= 100) {
aGrade[count] = Double.parseDouble(input); //put into the array
count++; //only increment count if success
ok = true;
}
} catch (NumberFormatException nfe) {
// nothing
}
if (!ok) {
System.out.println("That wasn't a valid percentage,"
+ " I need a number between 0-100. Try again.");
}

How to print two different data type arrays?

Can anyone help?
Choice 2 isn't working. It is suppose to display the employee ID when the user inputs the employee Name, but when the user enters the name nothing prints. The code has no errors.
public static void main(String[] args) {
int[] emplID={ 42577, 38611, 32051, 28627, 42061, 79451 };//employee ID
int ID = employeeID(emplID);
String[] emplNames= { "Bruce Wayne", "Barry Allen", "Hal Jordan", "Dinah Lance", "Oliver Queen", "Tineil Charles" };// Employee Names
search(emplNames, emplID);
//methods called from main
}
public static int employeeID(int [] emplID) {
//check ID length
for(int i=0; i< emplID.length; i++) {
if((emplID[i] > 10000)&&(emplID[i] < 99999)) {
System.out.print(emplID[i] + " - Valid ID length\n");
}
else {
System.out.println(emplID[i] + " - Invalid ID! ID must be Five digits!\n");
}//end of check length
//check if ID is prime
boolean isPrime = true;
for (int j = 2; j < emplID[i]; j++) {
if (emplID[i] % j == 0) {
System.out.println(emplID[i] + " - not prime");
isPrime = false;
break;
}
}
if(isPrime) System.out.println(emplID[i] + " - valid prime");//end of check prime
}//end of employeeID method
return 0;
}// end of ID checker
// search employee data
public static void search(String[] emplNames, int[]emplID) {
Scanner scan= new Scanner(System.in);
//Menu Choice
System.out.println("Please choose 1 to enter Employee ID or 2 to enter Employee Name:" );
int num = scan.nextInt();//input choice
// Choice 1 to enter ID to display name
if (num == 1) {
System.out.println("Please enter Employee ID:");
int searchID= scan.nextInt();
for(int ID = 0; ID < emplID.length; ID++) {
if (searchID == (emplID[ID])){
System.out.println("Name: "+ emplNames[ID]);
}
}
}
// Choice 2 to enter name to display ID
else if(num == 2) {
System.out.println("Please enter Employee Name");
String searchName= scan.next();
for(int ID = 0; ID< emplID.length; ID++){
if ((searchName.equals(emplNames[ID]))){
System.out.println("ID: " + emplID[ID]);
}
}
}
else
System.out.println("Employee Not Found");
}
}
I copied and pasted your code and ran it on my machine. Yes, choice 2 was not working for me either.
Before reading your code completely my gut feeling was that the cause of failure was in using the Scanner class to get the name of the employee. I have had similar issues in the past and the best move is to learn to use the InputStreamReader and BufferedStreamReader objects.
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
1: I didn't do anything to your main()
public static void main(String[] args) {
int[] emplID={ 42577, 38611, 32051, 28627, 42061, 79451 };//employee ID
int ID = employeeID(emplID);
String[] emplNames= { "Bruce Wayne", "Barry Allen", "Hal Jordan", "Dinah Lance", "Oliver Queen", "Tineil Charles" };// Employee Names
search(emplNames, emplID);
}
2: I didn't do anything to your employeeID() function
public static int employeeID(int [] emplID) {
//check ID length
for(int i=0; i< emplID.length; i++) {
if((emplID[i] > 10000)&&(emplID[i] < 99999)) {
System.out.print(emplID[i] + " - Valid ID length\n");
}
else {
System.out.println(emplID[i] + " - Invalid ID! ID must be Five digits!\n");
}//end of check length
//check if ID is prime
boolean isPrime = true;
for (int j = 2; j < emplID[i]; j++) {
if (emplID[i] % j == 0) {
System.out.println(emplID[i] + " - not prime");
isPrime = false;
break;
}
}
if(isPrime) System.out.println(emplID[i] + " - valid prime");//end of check prime
}//end of employeeID method
return 0;
}// end of ID checker
3: It's in your search() method where I first created the InputStreamReader and the BufferedReader:
public static void search(String[] emplNames, int[]emplID) {
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader buff = new BufferedReader(in);
//Menu Choice
System.out.println("Please choose 1 to enter Employee ID or 2 to enter Employee Name:" );
int num = 0;
try {
num = Integer.parseInt(buff.readLine());
} catch (Exception e) {
e.printStackTrace();
}
4: Since choice 1 works fine, all I did was change your for loop to a for-each loop to make it easier to read.
// Choice 1 to enter ID to display name
if (num == 1) {
System.out.println("Please enter Employee ID:");
int searchID = 0;
try {
searchID = buff.read();
} catch (Exception e) {
e.printStackTrace();
}
for (int i : emplID) {
if (searchID == i) {
System.out.println("Name: " + emplNames[i]);
}
}
5: Here is what I did to make your 2nd Option work. Again, get the String from user via BufferedReader object's readLine() method. Then, it was just letting your for-loop searching for a match. That's it. Afterward, I ran the program and tested it for all the names you had above, works fine.
} else if (num == 2) {
System.out.println("Please enter Employee Name");
String searchName = "";
try {
searchName = buff.readLine();
} catch(Exception e) {
e.printStackTrace();
}
for(int ID = 0; ID< emplID.length; ID++){
if ((searchName.equals(emplNames[ID]))){
System.out.println("ID: " + emplID[ID]);
}
}
} else {
System.out.println("Employee Not Found");
}
}
}
6: Yeah, Scanner has an issue where it either doesn't read the entire line or you need to flush the stream before getting the input. It caused a lot of problems for me in a bunch of easy programs. Then I switched to using the InputStreamReader and BufferedStreamReader combo. Just wrap them in try-catch blocks, and you're fine. Look into it, it will the behavior of your code and your life a lot easier.
7: I hope this was helpful.

Java guess game. How do I use data validation to check if a number is within a certain range?

I need help coding a set of statements of data validation that checks if a user entry is within a range of 0 and 100, and anything the user types that ISNT a non-decimal integer between 1 and 100 should display an error message. Also I need a way to code how I can get a "goodbye" output to only display if the user enters "n" not "n" and "y." N meaning no and y meaning yes.
Heres my code.
import java.util.Scanner;
public class GuessingGameCalc {
private static void displayWelcomeMessage(int max) {
System.out.println("Welome to the Java Guessing Game!");
System.out.println(" ");
System.out.println("I'm thinking of a number between 1 and" + " " + max + " " + "let's see if you guess what it is!");
System.out.println(" ");
}
public static int calculateRandomValue(int max) {
double value = (int) (Math.random() * max + 1);
int number = (int) value;
number++;
return number;
}
public static void validateTheData(int count) {
if( count < 3) {
System.out.println("Good job!");
} else if (count < 7) {
System.out.println("Need more practice.");
} else{
System.out.println("Need way more practice.");
}
}
public static void main(String[] args) {
final int max = 100;
String prompt = "y";
displayWelcomeMessage(max);
int unit = calculateRandomValue(max);
Scanner sc = new Scanner(System.in);
int counter = 1;
while (prompt.equalsIgnoreCase("y")) {
while (true) {
System.out.println("Please enter a number.");
int userEntry = sc.nextInt();
if (userEntry < 1 || userEntry > max) {
System.out.println("Invalid guess! Guess again!");
continue;
}
if (userEntry < unit) {
if ( (unit - userEntry) > 10 ) {
System.out.println("Way Too low! Guess higher!");
} else {
System.out.println("Too low! Guess higher!");
}
} else if (userEntry > unit) {
if( (userEntry - unit) > 10 ){
System.out.println("Way Too high! Guess lower!");
} else {
System.out.println("Too high! Guess lower!");
}
} else {
System.out.println("Congratulations! You guessed it in" + " " + counter + " " + "tries!\n");
validateTheData(counter);
break;
}
counter++;
}
System.out.println("Would you like to try again? Yes or No?");
prompt = sc.next();
System.out.println("Goodbye!");
}
}
}
Instead of using .nextInt() rather use .nextLine(), which returns a String and then parse it to an int and catch the NumberFormatException
So basically you'll have this structure:
try {
int userEntry = Integer.parseInt(sc.nextLine());
...
} catch (NumberFormatException nfe) {
System.out.println("Please enter a valid number.");
}
Oh, just a comment on the rest of your code. You don't really need two while loops, one will be more than sufficient.

Catch invalid input and return to input prompt JAVA

I am very new to Java and as part of my college course I have to write a program that carries out some basic functions. Part of this program is that it needs to calculate the factorial of a number that the user inputs. If the user inputs a negative number then it must prompt for a positive number. I have got it to do this.
But if the user enters a fraction such as 2.2 then the program should present the user with an error and prompt for valid data. I believe some sort or try-catch should be implemented but so far I have had no success in getting this to work, after spending many hours on it. Any ideas how to get the program to catch the InputMismatchException error and prompt user for input again?
The relevant block of code from the program is below...
public static void factorialNumber() {
int factorial = 1;
boolean valid;
int number = 0;
do {
System.out.println("Please enter a number: ");
number = sc.nextInt();
valid = number > 0;
if (!valid) {
System.out.println("ERROR Please enter a positive number");
}
} while (!valid);
if (number < 0) {
System.out.println("***Error***: Please enter a positive number ... ");
factorialNumber();
}
if (number > 0) {
System.out.print("The factorial is: " + number + " ");
}
for (int i = 1; i <= number; i++) {
factorial *= i;
if ((number - i) > 0) {
System.out.print("x " + (number - i) + " ");
}
}
System.out.println("= " + factorial);
}
You can use Double class to parse the user input and then get only correct values. Like this:
public static void factorialNumber() {
int factorial = 1;
boolean valid;
int number = 0;
String userInput;
do {
System.out.println("Please enter a number: ");
userInput = sc.nextLine();
valid = validateUserInput(userInput);
} while (!valid);
number = Double.valueOf(userInput).intValue();
System.out.print("The factorial is: " + number + " ");
for (int i = 1; i <= number; i++) {
factorial *= i;
if ((number - i) > 0) {
System.out.print("x " + (number - i) + " ");
}
}
System.out.println("= " + factorial);
}
private static boolean validateUserInput(String userInput) {
if (userInput == null) {
System.out.println("You should enter a number!");
return false;
}
Double userInputNumber;
try {
userInputNumber = Double.valueOf(userInput);
} catch (Exception e) {
System.out.println("Please enter a valid number value.");
return false;
}
if (userInputNumber <= 0) {
System.out.println("ERROR Please enter a positive number");
return false;
} else if (userInputNumber - userInputNumber.intValue() > 0) {
System.out.println("ERROR You entered a fractional number!");
return false;
}
return true;
}

How to stop do while loop after 6 array inputs?

public class AppointmentSchedule {
private static final int NUM_APPOINTMENTS = 6;
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] scheduled = new String[NUM_APPOINTMENTS];
Scanner consoleScanner = new Scanner(System.in);
int i;
String name;
for (int z = 0; z < NUM_APPOINTMENTS; z++) {
scheduled[z] = "";
}
System.out.println("To schedule an appointment, Please enter a time between 1PM to 6PM");
do {
i = consoleScanner.nextInt();
try {
if (i >= 1 && i <= 6) {
try {
if (scheduled[i] == "") {
System.out.println("Please enter your name.");
name = consoleScanner.next();
scheduled[i] = name;
System.out.println("Thank you " + name
+ ", you have been scheduled for " + i
+ " PM.\n");
System.out
.println("To schedule an appointment, Please enter a time between 1PM to 6PM");
} else {
throw new TimeInUseException();
}
} catch (TimeInUseException ex1) {
System.out.println(ex1.getMessage());
}
} else
throw new InvalidTimeException();
} catch (InvalidTimeException ex) {
System.out.println(ex.getMessage());
}
} while ();
consoleScanner.close();
}
}
What are some techniques to end the do while loop after scheduled[i] is filled up with 6 elements?
Would it look like: while (scheduled[z] != 6)?
Do this while(i<=5); this will let your loop run even when i=6 here i is the variable you keep incrementing
Just keep track of how many inputs the user has made. This can be done by declaring
int count = 0;
before the do...while loop and incrementing it from the body of the inner if:
if (scheduled[i - 1] == "") {
System.out.println("Please enter your name.");
name = consoleScanner.next();
scheduled[i - 1] = name;
System.out.println("Thank you " + name
+ ", you have been scheduled for " + i
+ " PM.\n");
count++; /* Note this */
System.out.println("To schedule an appointment, Please enter a time between 1PM to 6PM");
}
and finally, change the condition to
} while (count < 6);

Categories

Resources