Ignoring invalid data from file in Java - java

I'm trying to create a program that reads in a list of integers from a file, and adds them all together and displays to the user. I can get this program to work properly but what I want to do is have it so if there is an invalid entry in the file (say, a word or anything that isn't a number) it will alert the user and ignore the invalid data and skip to the next available number. Here is my code so far:
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.util.InputMismatchException;
public class IntegerReadIn {
public static void main(String[] args) {
int sum = 0;
try {
File myFile = new File("IntegerReadIn.txt");
Scanner scan = new Scanner(myFile);
while (scan.hasNextInt()) {
sum = sum + scan.nextInt();
}
System.out.println("Total = " + sum);
scan.close();
} catch (FileNotFoundException e) {
System.err.println("No such file name");
} catch (InputMismatchException e) {
System.err.println("Invalid entry found - integers only.");
}
}
}

First use nextLine() to read the entire line. after that Use Integer.parseInt() method to validate the integer input.
Scanner scan = new Scanner(myFile);
String s = scan.nextLine();
try{
Integer.parseInt(s);
}
catch(NumberFormatException ex){
System.out.println("Error....");
}

Perhaps instead of using your while for only hasNextInt() you should loop for haxNext()
That way you can explicitly check if you get an integer or not (and thus you can provide feedback to the user)
while (scan.hasNext()) {
if (scan.hasNextInt()) {
sum = sum + scan.nextInt();
} else {
System.out.println("Invalid Entry: " + scan.next());
}
}
Having this in consideration you will not be needing the InputMismatchException

Related

Java Conditional Statement Exercises: Input numbers from keyboard and find their sum and use input "EXIT "to break the loop

I'm trying to create a loop by entering the number to be added and then blocking the loop with a "exit" input from the user..but it's not working properly.
import java.util.Scanner;
public class main {
public static void main(String[] args)
{
int i,n=0,s=0;
double avg;
{
System.out.println("Input the numbers : ");
}
for (i=0;i<100;i++)
{
String input = new java.util.Scanner(System.in).nextLine ();
if(input.equals("exit")){
break;
}
Scanner in = new Scanner(System.in);
n = in.nextInt();
s +=n;
}
System.out.println("The sum of numbers is : " +s);
}
}
You have a couple of problems. One (minor) is that you are creating two scanners. Another (medium) is that your loop is set up to only go up to 100 - this is a magic number, and there's no reason to put in this artificial constraint. But your biggest problem is that you are ignoring the first entry in the loop if it is a number and not 'exit'
{
int i,n=0,s=0;
double avg;
boolean adding = true;
System.out.println("Input the numbers : ");
Scanner sc = new java.util.Scanner(System.in);
while(adding)
{
String input = sc.nextLine ();
if(input.equals("exit")){ // should proably be "EXIT" or equalsIgnoreCase
adding = false;
} else {
try {
int val = Integer.parseInt(input);
s += val;
} catch (NumberFormatException nfe) {
System.err.println ("expecting EXIT or an integer");
}
}
}
System.out.println("The sum of numbers is : " +s);
}
After this line your console does not have any next line or entry to read.
String input = new java.util.Scanner(System.in).nextLine ();

Java (Read and write to file)

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class backup {
public static void main(String[] args) {
System.out.println("\nThe names in the file are:\n");
readFromFile();
}
public static void readFromFile() {
try {
Scanner file = new Scanner(new File("Names.txt"));
PrintWriter pass = new PrintWriter("pass.txt");
PrintWriter fail = new PrintWriter("fail.txt");
Scanner input = new Scanner(System.in);
while (file.hasNext()) {
String name = file.nextLine();
System.out.printf("Please enter " + name + "'s mark:");
int mark = input.nextInt();
Scanner kybd = new Scanner(System.in);
{
if (mark >= 40) {
// System.out.println(name + " has passed");
pass.println(name);
} else {
// System.out.println(name + " has failed");
fail.println(name);
}
}
} // end while
} // end try
catch (IOException ioe) {
System.out.println("Error handling file");
} // end catch
}// readFromFile
}
Unable to write to the file pass and fail the Names file is just a list of names if the user scores over 40 they go into the pass however i cant get the txt file to populate the output.
When i insert my printwriter in the while it is only the last entry which gets added to either pass or fail txt file.
The PrintWriter only really writes when they are closed (close) or flushed (flush or maybe when it thinks it is time ;-)).
Try to use try-with-resources whenever possible, that way you do not need to think about closing/flushing a stream or writer. try-with-resources takes care that AutoClosable-implementations are closed automatically at the end of the try-block.
Your sample rewritten with try-with-resources (only showing the initial part):
try(
Scanner file = new Scanner(new File("Names.txt"));
PrintWriter pass = new PrintWriter("pass.txt");
PrintWriter fail = new PrintWriter("fail.txt")
) {
The rest can stay as is... or if you like: you may also want to lookup the Files-API. Maybe using Files.lines is something for you?
You should call the function close on your file for it to be written on the dsisk.
Otherwise you modifications are only in memory
Something like: file.close()
If you use PrintWriter, you have to close the stream at the end. Otherwise, it will be only in memory. Try this:
try {
Scanner file = new Scanner(new File("Names.txt"));
PrintWriter pass = new PrintWriter("pass.txt");
PrintWriter fail = new PrintWriter("fail.txt");
Scanner input = new Scanner(System.in);
while (file.hasNext()) {
String name = file.nextLine();
System.out.printf("Please enter " + name + "'s mark:");
int mark = input.nextInt();
//Scanner kybd = new Scanner(System.in);
//{
if (mark >= 40) {
// System.out.println(name + " has passed");
pass.println(name);
} else {
// System.out.println(name + " has failed");
fail.println(name);
}
//}
} // end while
pass.close();
fail.close();
} // end try
catch (IOException ioe) {
System.out.println("Error handling file");
}
You need to make sure that you add a finally block at the end and call the close method on anything that is closeable so in this case on the printwriter. In this case
pass.close() and fail.close().

Going through a txt file and finding sum of integers with exception

I have program that is suppose to ask the user what txt file, go through the txt file and find all parsable ints and average them. I have the following code below, but it's giving me a bunch of errors. What is the cause of all these errors?
The txt file is:
5
15
312
16
eight seven 44
eighty-five thousand and sixty-two 13 98
93
import java.util.Scanner;
public class Ch12Pt2 {
public static void main(String[] args) throws NumberFormatException {
Scanner input = new Scanner(System.in);
System.out.print("Enter filename: ");
String filename = input.nextLine();
Scanner file = new Scanner(filename);
if(file.nextLine().equals(""))
{
System.err.println("Could not find file:" + filename);
System.exit(1);
}
do {
try {
int total = 0;
int count = 0;
int num = file.nextInt();
total = num + total;
//Display the results
System.out.println("The number of parsable numbers: " + count);
System.out.println("Average values: " + (total / count));
}
catch (NumberFormatException ex) {
System.out.println("Cannot parse " + num + " as an integer.");
file.nextInt();
}
} while (file.hasNextInt());
// Close the files
input.close();
file.close();
}
}
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Ch12Pt2.main(Ch12Pt2.java:21)
If you look at the JavaDoc for the constructor you used, you will that it "Constructs a new Scanner that produces values scanned from the specified string." What you want is Scanner#Scanner(File source), "...a new Scanner that produces values scanned from the specified file".
Do not use do-while, it will through a null pointer if your file does not have any integers. Use while instead. Also, do not initialize any of your variables inside the loop. This will cause them to re-initialize at ever iteration.
What is the point of file.nextInt(); in your catch block? It causes the program to skip an extra integer. Remove it. Furthermore, do not call input.close();, you do not want to close System.in.
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
System.out.println("Enter filename: ");
File file = new File(input.nextLine());
/*
* Check file existence before constructing your scanner. This will prevent a
* FileNotFoundException. Notice, I used File#exists and the NOT operator '!'
*/
if (!file.exists()) {
System.err.println("Could not find file: " + file.getName());
System.exit(0);
}
Scanner scanner = new Scanner(file);
// Initialize variables outside of loop.
int num = 0;
int total = 0;
int count = 1;
// No do-while
while (scanner.hasNextInt()) {
try {
num = scanner.nextInt();
total += num;
// Display the results
System.out.println("The number of parsable numbers: " + count);
System.out.println("Average values: " + (total / count));
// count is pointless unless you increase it after every number.
count++;
} catch (NumberFormatException ex) {
System.out.println("Cannot parse " + num + " as an integer.");
}
}
// Close the files
scanner.close();
Finally, as Mad Programmer pointed out, "eight seven" and "eighty-five thousand and sixty-two" are not numbers, thus Scanner#nextInt will not include them. A work around is to use Scanner#nextLine and parse accordingly. Something like this: How to convert words to a number?
Your code is all most all wrong. I have reworked it now it works.
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class Ch12Pt2 {
public static void main(String[] args) throws NumberFormatException, FileNotFoundException {
Scanner input = new Scanner(System.in);
System.out.print("Enter filename: ");
String filename = input.nextLine();
Scanner file = new Scanner(new FileReader(filename));
int num =0;
int count =0;
int total =0;
if(file.nextLine().equals(""))
{
System.err.println("Could not find file:" + filename);
System.exit(1);
}
while (file.hasNextInt()){
try {
num = file.nextInt();
total = num + total;
count++;
}
catch (NumberFormatException ex) {
System.out.println("Cannot parse " + num + " as an integer.");
}
}
// Close the files
input.close();
file.close();
System.out.println("The number of parsable numbers: " + count);
System.out.println("Average values: " + (total / count));
}
}
Scanner file = new Scanner(filename);
Exception in thread "main" java.util.NoSuchElementException
If you're reading data from a text file using a Scanner you need to specify a File, not a string, which is why you're getting the above error.
Use:
Scanner scanner = new Scanner(new FileReader("foo.txt"));
And then recursively go through the text file like this:
while(scanner.hasNext())
Your code:
while (file.hasNextInt());
Will not work because the hasNextInt() method will stop processing the text file when it encounters anything other than an integer.
System.out.println("Cannot parse " + num + " as an integer.");
Variable num is defined in a different scope to the body that handles the exception. An additional error will be thrown because num is not defined within the NumberFormatException body.
The txt file is: 5 15 312 16 eight seven 44 eighty-five thousand and sixty-two 13 98 93
If the items in the text file are on the same line it would be better to use the split method to get all elements and then detect whether they're numbers or not.
String line = sc.nextLine();
String elements = line.split(" ");
for (String e : elements) {
// add if int, or continue iteration
}
Otherwise, try something along the lines of:
int sum = 0;
int numElements = 0;
Scanner scanner = new Scanner(new FileReader("path-to-file"));
while (scanner.hasNext()) {
try {
int temp = Integer.parseInt(sc.nextLine());
sum += temp;
numElements += 1;
}catch(NumberFormatException e) {
continue;
}
}
System.out.println("Mean: "+ (sum/numElements));

Exception handling with a do-while loop in Java

The algorithm should take in 3 integers to an ArrayList. If the input is not an integer, then there should be a prompt. When I execute my code the catch clause is executed, but the program runs into a infinite loop. Could someone guide me into the right direction, I appreciate the help. :-D
package chapter_08;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class IntegerList {
static List<Integer> numbers = new ArrayList<Integer>();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int counter = 1;
int inputNum;
do {
System.out.print("Type " + counter + " integer: " );
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
}
catch (Exception exc) {
System.out.println("invalid number");
}
} while (!(numbers.size() == 3));
}
}
That is because when the next int is read using nextInt() and it fails, the Scanner still contains the typed contents. Then, when re-entering the do-while loop, input.nextInt() tries to parse it again with the same contents.
You need to 'flush' the Scanner contents with nextLine():
catch (Exception exc) {
input.nextLine();
System.out.println("invalid number");
}
Notes:
You can remove the counter variable, because you're not using it. Otherwise, you could replace counter += 1 by counter++.
You can replace while (!(numbers.size() == 3)) with while (numbers.size() != 3), or even better: while (numbers.size() < 3).
When catching exceptions, you should be as specific as possible, unless you have a very good reason to do otherwise. Exception should be replaced by InputMismatchException in your case.
If inputNum = input.nextInt(); cannot be fit into an int and a InputMismatchException is raised, the input of the Scanner is not consumed.
So after the catch, it loops and it goes again here :
inputNum = input.nextInt();
with exactly the same content in the input.
So you should execute input.nextLine(); in the catch statement to discard the current input and allow a new input from the user.
Besides it makes more sense to catch InputMismatchException rather than Exception as other exception with no relation with a mismatch could occur and it would not be useful to display to the user "invalid number " if it is not the issue :
catch (InputMismatchException e){
System.out.println("invalid number ");
input.nextLine();
}
You should to use a break; in your catch(){} like so :
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
} catch (Exception e) {
System.out.println("invalid number ");
break;
}
So if one input is not correct break your loop.
try changing
inputNum = input.nextInt();
to
String inputText=input.next();
inputNum = Integer.valueOf(inputText);
it works perfectly well.
You need to move the scanner to the next line. Add this line of code below the error message in the catch section.
input.nextLine();

Open file and read Double data

Trying to read double data from the file that has different contents. For example if it is a double then the message should be "Double number is 23.5". and if it is not double number the message should be "Sixty three is not a double number". The file contents are
97.9
100.1
Three
Sixty three
77
12.4
3002.4
76
Cool
34.6
This is it
............
The code i wrote opens the file and scans next line But does not seem to properly work.
class ReadDouble
{
Scanner scan = new Scanner(System.in);
try
{
File textFile = new File ("doubleData.txt");
Scanner scanFile = new Scanner (textFile);
String str = scan.nextLine();
while(scanFile.hasNextLine())
{
double num = Double.parseDouble(str);
if(str == num)
{
System.out.println("Double number is" + str);
}
}//end while
}//end try
catch (NumberFormatException nfe)
{
System.out.println(str + "Is not a Double number");
}
}
}//end class
your try-catch should be inside the while loop, else it will come out in the first exception and rest of the lines will be ignored.
First, you should call String str = scan.nextLine(); within the loop otherwise you only ever read the first line. Also, your try / catch block should be wrapped around double num = Double.parseDouble(str); within the while loop otherwise you will not make another call to scan.nextLine() after you encounter your first non-double.
Finally, you shouldn't do if(str == num) as this will always be false. If Double.parseDouble(str) does not throw an exception, it contains the double found on that line.
Here is a solution that reads from standard in:
import java.util.Scanner;
public class ReadDouble {
public static void main(String[] args){
Scanner scan = new Scanner (System.in);
while(scan.hasNextLine()){
String str = scan.nextLine();
try {
num = Double.parseDouble(str);
System.out.println("Double number is " + num);
} catch (NumberFormatException nfe) {
System.out.println(str + " is not a Double number");
}
}
}
}
Another option is to use Scanner to see if the next element is a double if it is read it using nextDouble() otherwise read using nextLine().
Given your file format, I would not bother with Scanner. Just read each line, pass it to Double.valueOf(String) and catch the exception if it is not a double.

Categories