So, I was looking for an efficient way, using Java's standard packages, to read an input integer... For example, I came across the class "Scanner", but I found two main difficulties:
if I don't insert an int, I'm not actually able to solve the exception;
this class works with tokens, but my aim is to load the string in its full length.
This is an example of execution I would like to realize:
Integer: eight
Input error - Invalid value for an int.
Reinsert: 8 secondtoken
Input error - Invalid value for an int.
Reinsert: 8
8 + 7 = 15
And this is the (incorrect) code I tried to implement:
import java.util.Scanner;
import java.util.InputMismatchException;
class ReadInt{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
boolean check;
int i = 0;
System.out.print("Integer: ");
do{
check = true;
try{
i = in.nextInt();
} catch (InputMismatchException e){
System.err.println("Input error - Invalid value for an int.");
System.out.print("Reinsert: ");
check = false;
}
} while (!check);
System.out.print(i + " + 7 = " + (i+7));
}
}
Use a BufferedReader. Check NumberFormatException. Otherwise very similar to what you have. Like so ...
import java.io.*;
public class ReadInt{
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
boolean check;
int i = 0;
System.out.print("Integer: ");
do{
check = true;
try{
i = Integer.parseInt(in.readLine());
} catch (NumberFormatException e){
System.err.println("Input error - Invalid value for an int.");
System.out.print("Reinsert: ");
check = false;
}
} while (!check);
System.out.print(i + " + 7 = " + (i+7));
}
}
To use with tokens:
int i = Integer.parseInt(in.next());
Then you could do:
int i;
while (true) {
System.out.print("Enter a number: ");
try {
i = Integer.parseInt(in.next());
break;
} catch (NumberFormatException e) {
System.out.println("Not a valid number");
}
}
//do stuff with i
That above code works with tokens.
Related
This question already has answers here:
What does a "Cannot find symbol" or "Cannot resolve symbol" error mean?
(18 answers)
Closed 12 months ago.
I keep running into this error when compiling this code here:
TryTryAgain.java:52: error: cannot find symbol
if (file.hasNextInt()) {
^
symbol: variable file
location: class TryTryAgain
It's not picking up the file symbol I defined in the try-catch block within that do-while loop while compiling. I'm not really sure how to fix this as it has to be in there or else I wouldn't be able to throw the exception and repeat until a valid file name is given.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.NoSuchElementException;
import java.io.IOException;
import java.util.InputMismatchException;
public class TryTryAgain {
public static void main(String[] args) {
Scanner userInp = new Scanner(System.in);
System.out.print("Please enter the name of the file: ");
String userFile = userInp.next();
boolean fileAccepted = false;
do {
try {
Scanner file = new Scanner(new File(userFile));
fileAccepted = true;
} catch (FileNotFoundException e) {
System.out.println(userFile + " (The system cannot find the file specified)");
System.out.print("Please enter a valid file name: ");
userFile = userInp.next();
}
} while (fileAccepted == false);
int currentHighest = 0;
int currentLowest = 2147483647;
int totalOf = 0;
double totalNums = 0.0;
int currentNum;
//Making these to make the output look like the example ones
String total = "Total";
String min = "Min";
String max = "Max";
String average = "Average";
do {
if (file.hasNextInt()) {
totalNums++;
currentNum = file.nextInt();
totalOf += currentNum;
if (currentHighest < currentNum) {
currentHighest = currentNum;
}
if (currentLowest > currentNum) {
currentLowest = currentNum;
}
} else if (file.hasNextLine()) {
System.out.println("Skipping over invalid input: " + file.nextLine());
} else if (file.hasNextDouble()) {
System.out.println("Skipping over invalid input: " + file.nextDouble());
}
} while (file.hasNextInt() || file.hasNextLine() || file.hasNextDouble());
file.close();
if (totalNums > 0) {
double averageVal = (totalOf / totalNums);
System.out.printf("%7s: %d", total, totalOf);
System.out.printf("%7s: %d", min, currentLowest);
System.out.printf("%7s: %d", max, currentHighest);
System.out.printf("%7s: %d", average, averageVal);
} else {
System.out.println("No valid data found. No stats available.");
}
} //end main
}
I would suggest using a try-with-resources statement and moving the processing logic and perhaps the display logic to their own separate methods. The try-with-resources means you don't need to explicitly call file.close() and you cannot forget, nor can it be missed if some RuntimeException occurs in your code due to a null pointer, input mismatch, or any other unexpected problem. Some people would frown on the while (true) here and exiting the loop with break; but I think it's cleaner than using the separate condition variable and is all right as long as the loop body is kept simple, which it is if you extract the processing and display logic to their own methods. But if you prefer the condition variable on the loop, that is of course always an option.
public static void main(String[] args) {
Scanner userInp = new Scanner(System.in);
System.out.print("Please enter the name of the file: ");
String userFile = userInp.next();
while (true) {
try (Scanner file = new Scanner(new File(userFile))) {
process(file);
break;
} catch (FileNotFoundException e) {
System.out.println(userFile + " (The system cannot find the file specified)");
System.out.print("Please enter a valid file name: ");
userFile = userInp.next();
}
}
}
public static void process(Scanner file) {
int currentHighest = 0;
int currentLowest = 2147483647;
int totalOf = 0;
double totalNums = 0.0;
int currentNum;
do {
if (file.hasNextInt()) {
totalNums++;
currentNum = file.nextInt();
totalOf += currentNum;
if (currentHighest < currentNum) {
currentHighest = currentNum;
}
if (currentLowest > currentNum) {
currentLowest = currentNum;
}
} else if (file.hasNextLine()) {
System.out.println("Skipping over invalid input: " + file.nextLine());
} else if (file.hasNextDouble()) {
System.out.println("Skipping over invalid input: " + file.nextDouble());
}
} while (file.hasNextInt() || file.hasNextLine() || file.hasNextDouble());
display(totalNums, totalOf, currentLowest, currentHighest);
}
public static void display(int totalNums, int totalOf, int lowest, int highest) {
String total = "Total";
String min = "Min";
String max = "Max";
String average = "Average";
if (totalNums > 0) {
double averageVal = (totalOf / totalNums);
System.out.printf("%7s: %d", total, totalOf);
System.out.printf("%7s: %d", min, lowest);
System.out.printf("%7s: %d", max, highest);
System.out.printf("%7s: %d", average, averageVal);
} else {
System.out.println("No valid data found. No stats available.");
}
}
You are referring to file that doesn't exist in the context of the do-while loop. You create and establish the file inside a try catch at the beginning of your class. Move the logic for opening/closing the file into a single try catch, and the try section should contain the logic for reading the file.
try
{
// logic for opening file
// log for reading (the do/while that processes the file)
}catch(FileNotFound){
How can I use any alternative to 'goto' in java?
I tried using break label. But since I am not breaking out of any loop, it is giving undefined label error.
import java.io.*;
class $08_02_Total_Avg_Marks
{
public static void main(String args[]) throws IOException
{
//declare and initialize variables
int subNo = 0, totalMarks = 0;
float avg = 0.0F;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
label1:
System.out.println("Enter no. of subjects");
//check if input is integer
try
{
subNo = Integer.parseInt(br.readLine().trim());
}
catch(NumberFormatException e)
{
System.out.println("Please enter a whole number.");
//goto label1
}
int[] marksArray = new int[subNo];
for(int i=0; i<marksArray.length; i++)
{label2:
System.out.println("Enter marks for subject " + (i+1));
try
{
marksArray[i] = Integer.parseInt(br.readLine().trim());
}
catch(NumberFormatException e)
{
System.out.println("Please enter a whole number.");
//goto label2
}
}
}
}
I was terminating the program on invalid input. But I need to execute the same lines on invalid input.
Rather than wanting to go to a specific point explicitly, wrap the bit you might want to repeat in a loop. If you don't want to execute the loop again, break.
For the first one:
while (true) {
System.out.println("Enter no. of subjects");
//check if input is integer
try
{
subNo = Integer.parseInt(br.readLine().trim());
break;
}
catch(NumberFormatException e)
{
System.out.println("Please enter a whole number.");
// Nothing required to continue loop.
}
}
For the second one, wrap the loop body in loop:
for(int i=0; i<marksArray.length; i++)
{
while (true) {
System.out.println("Enter marks for subject " + (i+1));
try
{
marksArray[i] = Integer.parseInt(br.readLine().trim());
break;
}
catch(NumberFormatException e)
{
System.out.println("Please enter a whole number.");
}
}
}
Or, probably better, write a method wrapping this loop:
int getInt(BufferedReader br) throws IOException {
while (true) {
try
{
return Integer.parseInt(br.readLine().trim());
} catch(NumberFormatException e) {
System.out.println("Please enter a whole number.");
}
}
}
and then call this method:
System.out.println("Enter no. of subjects");
int subNo = getInt(br);
for(int i=0; i<marksArray.length; i++) {
System.out.println("Enter marks for subject " + (i+1));
marksArray[i] = getInt(br);
}
This code snippet will loop until a correct number is inserted, in this example (it solves your first goto problem)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
boolean noNumberEntered; //Default on false
System.out.println("Enter no. of subjects");
//TODO: check if input is integer
while(!noNumberEntered){
try
{
subNo = Integer.parseInt(br.readLine().trim());
noNumberEntered = true;
}
catch(NumberFormatException e)
{
System.out.println("Please enter a whole number.");
}
}
I have reformatted your code a little bit. My basic idea was: All of the goto statements can be written in equivalent loops. The first one has now been made with a while loop, which terminates ones there comes NO exception. As for the second label, that has been done with the same mechanism (so a while-loop), however, with a label that can be exited/terminated with a "break + nameOfYourLable" - statement.
import java.io.*;
class $08_02_Total_Avg_Marks
{
public static void main(String args[]) throws IOException
{
//declare and initialize variables
int subNo = 0, totalMarks = 0;
float avg = 0.0F;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
boolean goToLabel1 = true;
while (goToLabel1) {
System.out.println("Enter no. of subjects");
//check if input is integer
try
{
subNo = Integer.parseInt(br.readLine().trim());
goToLabel1 = false; //parsing succeeded, no need to jump to label1
}
catch(NumberFormatException e)
{
System.out.println("Please enter a whole number.");
//goto label1
}
}
int[] marksArray = new int[subNo];
for(int i=0; i<marksArray.length; i++)
{
label2: while (true) {
System.out.println("Enter marks for subject " + (i+1));
try
{
marksArray[i] = Integer.parseInt(br.readLine().trim());
break label2;
}
catch(NumberFormatException e)
{
System.out.println("Please enter a whole number.");
}
}
}
}
}
You can use a do while loop and a boolean instead, like that :
class $08_02_Total_Avg_Marks
{
public static void main(String args[]) throws IOException
{
//declare and initialize variables
int subNo = 0, totalMarks = 0;
float avg = 0.0F;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
boolean goodEntry = true;
do {
goodEntry = true;
System.out.println("Enter no. of subjects");
//check if input is integer
try
{
subNo = Integer.parseInt(br.readLine().trim());
}
catch(NumberFormatException e)
{
System.out.println("Please enter a whole number.");
goodEntry = false;
}
} while(!goodEntry);
}
You can do the same with your second goto.
There are many ways to do that (with while loop and a boolean, with breaks...), but loops are better then goto.
So I'm trying to make a simple calculator.
How do I make when I enter the first number, it works but if I insert "abc" it will give me an error.
How I make it in order when you write "abc" to say " please enter a number "
import java.util.Scanner;
public class calculator
{
public static void main(String[] args0) {
Scanner test = new Scanner(System.in);
int x;
int y;
String c;
System.out.println("Insert a number ");
x = test.nextInt();
System.out.println("insert a value e.g * / + -");
c = test.next();
System.out.println("Insert another number");
y = test.nextInt();
if ( c.equals("*")) {
System.out.println("the total is " + x*y);
}
if (c.equals("+")) {
System.out.println("the total is " + (x+y));
}
if (c.equals("-")) {
System.out.println("the total is "+ (x-y));
}
if (c.equals("/")) {
System.out.println("the total is "+ (x/y));
}
}
}
You can verify the input until be a int using a scanner property Scanner.hasNextInt()
Scanner scanner = new Scanner(System.in);
System.out.print("Enter number 1: ");
while (!scanner.hasNextInt()) scanner.next();
Example:
public static void main(String[] args0) {
Scanner test = new Scanner(System.in);
int x;
int y;
String c;
System.out.println("Insert a number ");
while (!test .hasNextInt()) test .next(); // Scanner Validation
int x = test .nextInt();
}
JavaDoc of Scanner
The error you get is an exception. You can actually "catch" your exceptions, so that when they appear, your program doesn't break, and you can do what is in place for that error (output a "Please, insert only numeric values" feedback?)
You can find some info on try-catch blocks here try-catch blocks
Try this:
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner test = new Scanner(System.in);
int x;
int y;
String c;
try {
System.out.println("Insert a number ");
x = test.nextInt();
System.out.println("insert a value e.g * / + -");
c = test.next();
System.out.println("Insert another number");
y = test.nextInt();
if (c.equals("*")) {
System.out.println("the total is " + x*y);
}
if (c.equals("+")) {
System.out.println("the total is " + (x+y));
}
if (c.equals("-")) {
System.out.println("the total is "+ (x-y));
}
if (c.equals("/")) {
System.out.println("the total is "+ (x/y));
}
} catch(InputMismatchException e) {
System.out.println("Please enter correct values.");
}
}
Modifications:
The error you are getting is known as RunTime Error or Exceptions due to wrong input type. In order to handle RunTime Exceptions, You need to use try and catch block.
try and catch blocks are used to handle RunTime Exceptions. If any error or exception occurs within try block then It will be thrown to catch block to be handled instead of terminating your program.
Try this:
boolean success = false;
while (!success) {
try {
y = test.nextInt();
success = true;
} catch (InputMismatchException e) {
test.nextLine();
System.out.println("Please enter a number.");
}
}
If you're willing to accept doubles instead of ints, java doubles have a built in method isNaN(), where NaN stands for Not a Number.
if (Double.isNaN(doubleValue)) {
...
}
I'm trying to make a method that gets the user's input of 6 numbers and add them to a Tree set of integers. I'm trying to make a try and catch exception so if the users accidentally enters in a letter it'll catch the exception and ask them to enter in a number. Right now the program crashes when you try to enter in a letter. It'll print out "Invalid" then crashes. I'm not sure whats going on. Can anyone provide some insight?
public static Set<Integer> getTicket()
{
int userInput;
TreeSet<Integer> getNumbers = new TreeSet<Integer>();
Scanner input = new Scanner(System.in);
System.out.println("Enter your 6 numbers between 1-40: ");
for (int i = 0; i<6 ; i++)
{
try
{
System.out.print(i+1 + ": ");
userInput = input.nextInt();
}
catch (InputMismatchException e)
{
System.out.println("Invalid");
userInput = input.nextInt();
}
getNumbers.add(userInput);
}
System.out.println("Your ticket was: " + getNumbers);
return getNumbers;
}
Just a few notes on some of the changes made. From your original code, one thing I noticed that is not really an error but a head scratcher. Both of your methods (getWinning Numbers() and getTicket() ) returned a Set<integer> set, however you did not use it in main. So I simply took the output from the methods and placed them in the main method, where they should be IMHO. Methods like these should do ONE thing and in this case is return a set of integers. No printing or anything else that’s all it does.
I changed the logic in the getTicket() method. I simply set up a loop that continued until you had 6 valid numbers. Inside that loop I use a try statement to weed out the invalid input. The way the try statement is set up is one of many ways that you could accomplish this. As you can see the statement immediately after the try (guess = Integer.parseInt(userInput);) is where the invalid input problem could pop up and throw a NumberFormatException. If the input is invalid, you drop immediately to the catch where we output a message and continue. If the input is valid then we simply check for duplicates and the range of the number. If the numbers are ok then add it to pickedNumbers and increment numberCount.
public class Lottery
{
public static Set<Integer> generateWinningNumbers()
{
Random rndNumbers = new Random();
TreeSet<Integer> winningNumbers = new TreeSet<Integer>();
int max = 40;
int min = 1;
int range;
int sixNum;
for (int i = 0; i < 6; i++)
{
range = max - min + 1;
sixNum = rndNumbers.nextInt(range) + min;
while (winningNumbers.contains(sixNum))
{
sixNum = rndNumbers.nextInt(range) + min;
}
winningNumbers.add(sixNum);
}
return winningNumbers;
}
public static Set<Integer> getTicket(Scanner input)
{
String userInput;
int guess;
TreeSet<Integer> pickedNumbers = new TreeSet<Integer>();
System.out.println("Enter your 6 numbers between 1-40: ");
int numberCount = 1;
while(numberCount < 7)
{
System.out.print(numberCount + ": ");
userInput = input.nextLine();
try
{
guess = Integer.parseInt(userInput);
if( guess > 0 && guess < 41 && (!pickedNumbers.contains(guess)) )
{
pickedNumbers.add(guess);
numberCount++;
}
else
{
if (pickedNumbers.contains(guess))
{
System.out.println("Number already picked: " + guess);
}
else
{
System.out.println("Invalid number. Pick a number between 1-40: " + guess);
}
}
}
catch (NumberFormatException e)
{
// bad input
System.out.println("Invalid input: " + userInput);
}
}
return pickedNumbers;
}
}
Changes in the Main now take advantage of the methods returning a Set of integers for us. We create two Set<Integer> variables (winningTicket and userTicket) then we simply get the returned sets from the methods and output the results as opposed to printing the results from the methods.
public static void main(String[] args) throws IOException
{
Scanner userInput = new Scanner(System.in);
boolean done = false;
String yesNo;
Set<Integer> winningTicket;
Set<Integer> userTicket;
while(!done)
{
winningTicket = Lottery.generateWinningNumbers();
userTicket = Lottery.getTicket(userInput);
System.out.println("Your ticket was: " + userTicket);
System.out.println("Winning Numbers: " + winningTicket);
System.out.print("\nWould you like to try again? ");
yesNo = userInput.nextLine();
if(!yesNo.equalsIgnoreCase("y"))
{
System.out.println("Done");
done = true;
}
}
userInput.close();
}
Hope this helps
This happens because you don't catch exceptions inside cath block. for loop doesn't look good here, try while:
public static Set<Integer> getTicket()
{
int userInput;
TreeSet<Integer> getNumbers = new TreeSet<Integer>();
Scanner input = new Scanner(System.in);
System.out.println("Enter your 6 numbers between 1-40: ");
int correct = 0;
while(correct < 6)
{
try
{
System.out.print((correct+1) + ": ");
userInput = input.nextInt();
getNumbers.add(userInput);
correct++;
}
catch (InputMismatchException e)
{
System.out.println("Invalid input");
}
}
System.out.println("Your ticket was: " + getNumbers);
return getNumbers;
}
Also you cant't print collection that simple:
System.out.println("Your ticket was: " + getNumbers);
What you can do, is to use streams:
System.out.println("Your ticket was: " + getNumbers.stream().map(Object::toString).collect(Collectors.joining(" ")));
I want to write a program which converts a binary number in a decimal.
Ive found out that the problem is that I cant even get the "catch path".
I also know that I have to change somthing with the char but I absolutely dont get a working solution. Thank you.
import java.util.Scanner;
public class BinaryStringToNumber {
public static void main(String[] args) {
String inputBinaer;
Scanner input = new Scanner(System.in);
System.out.print("Type in a binary number: ");
inputBinaer = input.next();
input.close();
try
{
convert(inputBinaer);
}
catch (NumberFormatException e)
{
System.out.println( "Just numbers!" );
} finally {
System.out.println( "Finally" );
}
}
public static void convert(String inputBinaer) throws NumberFormatException{
char [] puffer;
int dez = 0;
puffer = inputBinaer.toCharArray();
for(int i=0;i<puffer.length;i++){
if(puffer[i]== '1'){
dez = (int) (dez + Math.pow(2, puffer.length-1-i));
}
}
System.out.println("The decimal number is: " + dez);
}
}
To get to the catch block, an exception has to be thrown somewhere. Normally, the Java methods do this for you, but since you are parsing everything yourself, you will have to throw the exception. One way would be to add a throw statement to the convert() method whenever it encounters an invalid digit:
import java.util.Scanner;
public class BinaryStringToNumber {
public static void main(String[] args) {
String inputBinaer;
Scanner input = new Scanner(System.in);
System.out.print("Type in a binary number: ");
inputBinaer = input.next();
input.close();
try
{
convert(inputBinaer);
}
catch (NumberFormatException e)
{
System.out.println( "Just numbers!" );
} finally {
System.out.println( "Finally" );
}
}
public static void convert(String inputBinaer) throws NumberFormatException{
char [] puffer;
int dez = 0;
puffer = inputBinaer.toCharArray();
for(int i=0;i<puffer.length;i++){
if(puffer[i]== '1'){
dez = (int) (dez + Math.pow(2, puffer.length-1-i));
} else if (puffer[i] != '0') {
throw new NumberFormatException("Invalid digit: " + puffer[i]);
}
}
System.out.println("The decimal number is: " + dez);
}
}
You need to specify where do you throw the NumberFormatException. I'd put an if in the for loop where I'd check the char, and if it was not a '0' or a '1', I'd throw an exception. Hope I helped.
You can throw NumberFormatException in case of bad input. That is allowed in Java.