Note: Desire to move this to Code Review with a clearer structure for answer and my modified code which was very similar to the answer besides calcmin method.
I'm trying to break this code up into multiple methods and I was successful with the first bit but the other two I can't seem to figure out.
With the second method I was trying to make it so it would ask the user for an integer and continually prompts them until a proper integer is entered.
With the third method I was trying to make it so that it takes three integer parameters and returns the minimum value of those parameters.
I'd really appreciate the help on this. I've looked through examples in my book and can't seem to get it.
My code:
import java.util.Scanner;
public class MinOfThreeInts
{
public static void intro ()
{
System.out.println("This program determines the minimum of three ints");
System.out.println("It gracefully reports errors when erroneous data is entered ");
System.out.println("For example, if you type in 'abc' when this program asked for an int");
System.out.println("the program will report the error & ask for another int");
System.out.println("Try giving it bad input ! \n\n");
}
public static void readInt (int value1, int value2, int value3)
{
System.out.print(" Please enter an integer value ");
Scanner console = new Scanner(System.in);
String input = console.nextLine();
Boolean goodInt;
int parsedValue = 0;
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value1 = parsedValue;
// Get the second integer
System.out.print(" Please enter an integer value ");
input = console.nextLine();
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value2 = parsedValue;
// Get the third integer
System.out.print(" Please enter an integer value ");
input = console.nextLine();
goodInt = false;
while (!goodInt)
{
try
{
parsedValue = Integer.parseInt(input);
goodInt = true;
}
catch(NumberFormatException ex)
{
System.out.print(" Invalid input, please enter Int ");
input = console.nextLine();
}
}
value3 = parsedValue;
}
public static void calcMin (min)
{
int min = value1;
if (value2 < min)
{
min = value2;
}
if (value3 < min)
{
min = value3;
}
// Now report the results
System.out.println(" The minimum value of the three ints is " + min);
}
public static void main(String[] args)
{
value1 = readInt(console);
value2 = readInt(console);
value3 = readInt(console);
min = calcMin(value1,value2,value3);
}
}
You have a couple of issues. I refactored your code and added comments, I stayed close to your code in order to give you insights on where you can improve.
First, the code:
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class MinOfThreeInts {
//the main method, things start here
public static void main(String[] args) {
//initialize a new scanner that the application will use
Scanner console = new Scanner(System.in);
//print the intro
intro();
//read the values one by one and save them in a variable
int value1 = readInt(console);
int value2 = readInt(console);
int value3 = readInt(console);
//calculate the minimum and save it in the min variable
int min = calcMin(Arrays.asList(value1,value2,value3));
// Now report the results
System.out.println(" The minimum value of the three ints is " + min);
}
/**
* Reads an integer from the given console
*/
public static int readInt(Scanner console) {
System.out.print(" Please enter an integer value ");
//read the input
int parsedValue = 0;
boolean goodInt = false;
//as long as we don't find a valid number
while (!goodInt)
{
try
{
//read the input
String input = console.nextLine();
//try to parse the value
parsedValue = Integer.parseInt(input);
//set goodInt to true so that the while loop will end
goodInt = true;
}
catch(NumberFormatException ex)
{
//if the provivded value was not an integer, print a message and return to the start of the while loop
System.out.print(" Invalid input, please enter Int ");
}
}
return parsedValue;
}
/**
* calculates the minimum of a list of values
*/
public static int calcMin (List<Integer> values) {
//find the minimum and return the value
return Collections.min(values);
}
/**
* prints an intro message
*/
public static void intro () {
System.out.println("This program determines the minimum of three ints");
System.out.println("It gracefully reports errors when erroneous data is entered ");
System.out.println("For example, if you type in 'abc' when this program asked for an int");
System.out.println("the program will report the error & ask for another int");
System.out.println("Try giving it bad input ! \n\n");
}
}
Now, on what you can do to improve:
compile the code does not compile, always take care your code compiles and then slightly edit it until it compiles again
scope your code has multiple declared integers, the problem was that the values were not visible in other methods, if you declare a variable, say int value1 in some method, another method will not be able to see it. If you have another int value1 in that other method, it will only be visible in that specific method and it will actually be another variable
arguments vs return types methods take arguments and return something. The arguments are the input of the method and the returned value is the result of the method. Take for example your method: public static void readInt (int value1, int value2, int value3). This is a method that should read an integer value from the console. However, this method signature says it takes 3 integers as parameter. These integers would be passed by value, since they are primitive types, so you can not pass them, then fill them and then return them. There is also no return type, so the method is not returning something. Since the integer parameters value1, value2 and value3 are only visible in the method scope, you will loose your data. Compare with the new signature: public static int readInt(Scanner console). This method takes a console to read from as a parameter and returns an integer, the number that has been read. This method encapsulates the retry.
Related
I'm trying to make a program that evaluates a mathematic equation that's written one character or value per line at a time. The user will enter alternating numbers and operators, line by line, terminating with a ‘.’. That means I'm not trying to evaluate from a single string (and assume input will always alternate between number and operator).
I don't know how to make it so that it keeps taking input until the user types ".'
I also am not sure how to keep the value continuously changing as the user types the formula and how to store that.
Sample input:
1
+
6
-
3
.
The solution to your equation is: 4
import java.util.Scanner;
class Evaluator {
static int add (int a, int b)
{
return a + b;
}
static int multiply (int a, int b)
{
return a * b;
}
static int divide (int a, int b)
{
return a / b;
}
static int subtract (int a, int b)
{
return a - b;
}
static int modulus (int a, int b)
{
return a % b;
}
public static void main(String [] args)
{
Scanner input = new Scanner (System.in);
int a,b,c;
System.out.println("Enter the equation:");
a = input.nextInt();
String c = input.next();
b = input.nextInt();
if (c.contains("+")) {
int result = add (a,b);
}
else if (c.contains("*")) {
int result = multiply (a,b);
}
else if (c.contains("/")) {
int result = divide (a,b);
}
else if (c.contains("-")) {
int result = subtract (a,b);
}
else if (c.contains("%")) {
int result = modulus (a,b);
}
else if (c.contains(".")) {
break;
}
System.out.print("The solution to your equation is: " + result);
}
}
Your code is very close, in that you use Scanner next() and nextInt() in the correct order (to match the input rules). Here a while(true) loop is added around the pair of inputs; either a user enter a '.' and the loop breaks, or the user enters an operator followed by the next number. The result is kept up to date by using it repeatedly in the various math operators.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int b, result;
System.out.println("Enter the equation:");
result = input.nextInt();
while (true) {
String c = input.next();
if (c.contains(".")) {
break;
}
b = input.nextInt();
if (c.contains("+")) {
result = add(result, b);
} else if (c.contains("*")) {
result = multiply(result, b);
} else if (c.contains("/")) {
result = divide(result, b);
} else if (c.contains("-")) {
result = subtract(result, b);
} else if (c.contains("%")) {
result = modulus(result, b);
}
}
input.close();
System.out.print("The solution to your equation is: " + result);
}
Here is a simple while loop you can use to get input from the user. I have a check if it's a digit or something else. You can use this skeleton to grab input from the user and exit when someone presses "."
Scanner input = new Scanner (System.in);
int a,b,currentTotal = 0;
String inputFromUser = "nothing";
while(!inputFromUser.equals("."))
{
inputFromUser = input.nextLine(); //grab line by line
if(inputFromUser.matches("\\d+")){
//parse the number and set it to a value like a...
System.out.println("You entered a number: " + inputFromUser);
}
else if(!inputFromUser.equals(".")){
//check if you have value and try to apply your number to your current total
System.out.println("You entered something other than a number: " + inputFromUser);
}
}
If the user enters a number, set a variable to that number, perhaps a
If the user enters something other than a number and not a period then check if the input is a valid operation with your provided logic and apply it like operatorMethod(a, currentTotal)
I'm having a hard time with my second method, The method declaration is:
public static void displayOutput(int loopCount)
The method is called from the main() and is passed the valid input value which determines repetition. The method displays the output pattern only and returns nothing. Every 3rd line displays a space and 3 asterisks
I know I'm not calling each method right in the main() and I know that displayOutput(int loopCout) is wrong.
Could someone explain this to me or use an example that would help write the program?
public static void main(String[] args) {
int repeat;
Scanner goGet = new Scanner(System.in);
repeat = getValidValue(goGet); //Uncompilable source code -Erroneous sym type
displayOutput(repeat);
}
public static int getValidValue() {
int input;
do {
Scanner getInfo = new Scanner(System.in);
System.out.print("Enter an integer Greater than zero: --> ");
input = getInfo.nextInt();
} while (input <= 0);
return input;
}
public static int displayOutput(int loopCount) {
int i;
for (i = 0; i < loopCount; i++) {
System.out.print("The semester is ending soon. ");
System.out.print("The semester is ending soon. ");
System.out.print("The semester is ending soon.*** ");
}
return loopCount;
}
You are passing a value to method getValidValue which doesn’t take any value.
Also displayOutput is returning loopcount but you are not catching it anywhere so after asterisk it is not displaying anything.
I am a noob in programming.
I wanted to write code for a prog which asks user to enter value until an integer is entered.
public class JavaApplication34 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int flag = 0;
while(flag == 0) {
int x = 0;
System.out.println("Enter an integer");
try {
x = sc.nextInt();
flag = 1;
} catch(Exception e) {
System.out.println("error");
}
System.out.println("Value "+ x);
}
}
}
I think the code is correct and it should ask me to enter the value again if i have entered anything other than an integer.
But when i run it , and say i enter xyz
it iterates infinite time without asking me to enter the value.
test run :
Enter an integer
xyz
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
When a scanner throws an InputMismatchException, the scanner will not
pass the token that caused the exception.
Hence sc.nextInt() reads the same token again and throws the same exception again.
...
...
...
catch(Exception e){
System.out.println("error");
sc.next(); // <---- insert this to consume the invalid token
}
You can change your logic as shown below :
int flag = 0;
int x = 0;
String str="";
while (flag == 0) {
System.out.println("Enter an integer");
try {
str = sc.next();
x = Integer.parseInt(str);
flag = 1;
} catch (Exception e) {
System.out.println("Value " + str);
}
}
Here we have first read the input from Scanner and then we are trying to parse it as int, if the input is not an integer value then it will throw exception. In case of exception we are printing what user has enter. When user enters an integer then it will parsed successfully and value of flag will update to 1 and it will cause loop to exit.
In the error case, you need to clear out the string you've entered (for instance, via nextLine). Since it couldn't be returned by nextInt, it's still pending in the scanner. You also want to move your line outputting the value into the try, since you don't want to do it when you have an error.
Something along these lines:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int flag = 0;
while(flag == 0)
{
int x = 0;
System.out.println("Enter an integer");
try
{
x = sc.nextInt();
flag = 1;
System.out.println("Value "+ x);
}
catch (Exception e){
System.out.println("error");
if (sc.hasNextLine()) { // Probably unnecessary
sc.nextLine();
}
}
}
}
Side note: Java has boolean, there's no need to use int for flags. So:
boolean flag = false;
and
while (!flag) {
and
flag = true; // When you get a value
The answers to this question might help you
It makes use of Scanners .hasNextInt() function!
There are several questions I would like to ask, please refer the comment part I have added in the code, Thanks.
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
/* Task:
prompt user to read two integers and display the sum. prompt user to read the number again if the input is incorrect */
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean accept_a = false;
boolean accept_b = false;
int a;
int b;
while (accept_a == false) {
try {
System.out.print("Input A: ");
a = input.nextInt(); /* 1. Let's enter "abc" to trigger the exception handling part first*/
accept_a = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.nextLine(); /* 2. I am still not familiar with nextLine() parameter after reading the java manual, would you mind to explain more? All I want to do is "Clear Scanner Buffer" so it wont loop for the println and ask user to input A again, is it a correct way to do it? */
}
}
while (accept_b == false) {
try {
System.out.print("Input B: ");
b = input.nextInt();
accept_b = true;
} catch (InputMismatchException ex) { /*3. Since this is similar to the above situation, is it possible to reuse the try-catch block to handling b (or even more input like c d e...) exception? */
System.out.println("Input is Wrong");
input.nextLine();
}
}
System.out.println("The sum is " + (a + b)); /* 4. Why a & b is not found?*/
}
}
I am still not familiar with nextLine() parameter after reading the java manual, would you mind to explain more? All I want to do is "Clear Scanner Buffer" so it wont loop for the println and ask user to input A again, is it a correct way to do it?
The use of input.nextLine(); after input.nextInt(); is to clear the remaining content from the input stream, as (at least) the new line character is still in the buffer, leaving the contents in the buffer will cause input.nextInt(); to continue throwing an Exception if it's no cleared first
Since this is similar to the above situation, is it possible to reuse the try-catch block to handling b (or even more input like c d e...) exception?
You could, but what happens if input b is wrong? Do you ask the user to re-enter input a? What happens if you have 100 inputs and they get the last one wrong?You'd actually be better off writing a method which did this for, that is, one which prompted the user for a value and returned that value
For example...
public int promptForIntValue(String prompt) {
int value = -1;
boolean accepted = false;
do {
try {
System.out.print(prompt);
value = input.nextInt();
accepted = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.nextLine();
}
} while (!accepted);
return value;
}
Why a & b is not found?
Because they've not been initialised and the compiler can not be sure that they have a valid value...
Try changing it something more like.
int a = 0;
int b = 0;
Yes, it's okay. And will consume the non-integer input.
Yes. If we extract it to a method.
Because the compiler believes they might not be initialized.
Let's simplify and extract a method,
private static int readInt(String name, Scanner input) {
while (true) {
try {
System.out.printf("Input %s: ", name);
return input.nextInt();
} catch (InputMismatchException ex) {
System.out.printf("Input %s is Wrong%n", input.nextLine());
}
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int a = readInt("A", input);
int b = readInt("B", input);
System.out.println("The sum is " + (a + b));
}
I have put comment to that question line.
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean accept_a = false;
boolean accept_b = false;
int a=0;
int b=0;
System.out.print("Input A: ");
while (accept_a == false) {
try {
a = input.nextInt(); // it looks for integer token otherwise exception
accept_a = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.next(); // Move to next other wise exception // you can use hasNextInt()
}
}
System.out.print("Input B: ");
while (accept_b == false) {
try {
b = input.nextInt();
accept_b = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.next();
}
}
System.out.println("The sum is " + (a + b)); // complier doesn't know wheather they have initialised or not because of try-catch blocks. so explicitly initialised them.
}
}
Check out this "nextLine() after nextInt()"
and initialize the variable a and b to zero
nextInt() method does not read the last newline character.
I'm writing some Java code that'll make a guessing game, where a random number is generated based on your maximum value and you have to guess the correct number. You can also set the amount of attempts you can get. This is where the problem occurs.You see, you can set a number of attempts in number form or write out "unlimited". I have an example of the code that does this here with comments to help you out:
import java.util.Scanner;
public class Game{
public static int processMaxAttempts;
public static Scanner maxAttempts;
public static String processMaxAttempts2;
public static void main(String args[]){
//Prints out text
System.out.println("Fill in your maximum attempts OR write \"unlimited\".");
//Creates a scanner
maxAttempts = new Scanner(System.in);
//Looks at the scanner "maxAttempts" and reads its integer value
processMaxAttempts = maxAttempts.nextInt();
//Looks at the scanner "maxAttempts" and reads its string value
processMaxAttempts2 = maxAttempts.nextLine();
//Prints out "unlimited" if "maxAttempts" has a string value and "set" if it has an integer value
if(processMaxAttempts2.equals("unlimited")){
System.out.println("unlimited");
}else{
System.out.println("set");
}//Close else
}//Close main method
}//Close class
What happens is a get an error that says this:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:857)
at java.util.Scanner.next(Scanner.java:1478)
at java.util.Scanner.nextInt(Scanner.java:2108)
at java.util.Scanner.nextInt(Scanner.java:2067)
at com.pixelparkour.windows.MainGameWindow.main(MainGameWindow.java:34)
That error targets this line of code:
processMaxAttempts = maxAttempts.nextInt();
So... yeah. I have no idea. I'm very new to Java (I've been learning it for only 3 days) and I'm a bit helpless. I'd love to know what my problem is so I can apply to it the future and program some cool games!
You need to put a check on content type before reading the content.
What you need is :
if(maxAttempts.hasNextInt()){ // this will check if there is an integer to read from scanner
processMaxAttempts = maxAttempts.nextInt();
} else {
processMaxAttempts2 = maxAttempts.nextLine();
}
if(processMaxAttempts2!=null && processMaxAttempts2.equals("unlimited")){
System.out.println("unlimited");
}else{
System.out.println("set");
}
I think this is what you are looking for
public class Test
{
private int guessableNumber;
private Integer maxAttempts;
public Test()
{
maxAttempts = 0;
}
public void doYourStuff(){
Scanner scan = new Scanner(System.in);
Random random = new Random();
System.out.println("Please enter your amount of guesses or type unlimited for unlimited guesses");
String s = scan.next();
if(s.toUpperCase().equals("UNLIMITED")){
guessableNumber = random.nextInt(100);
}
else {
try{
maxAttempts = Integer.parseInt(s);
guessableNumber = random.nextInt(100) + Integer.parseInt(s);
}catch(Exception e){
System.out.println("You did not enter a valid number for max attempts");
}
}
int counter = 0;
System.out.println("Type in a guess");
while(scan.nextInt() != guessableNumber && counter <=maxAttempts){
System.out.println("You did not guess correctly try again");
++counter;
}
if(counter > maxAttempts){
System.out.println("You have exceeded your max attempts");
}
else {
System.out.println("Correct you guessed the correct number: "+ guessableNumber);
}
}
public static void main(String[] args)
{
Test test = new Test();
test.doYourStuff();
}
}
One little trick that always works for me is just going ahead and making a second scanner, i.e. num and text, that way you can always have one looking for int values and the other dealing with the Strings.