How do I fix a NumberFormatException (from text file input)? - java

I was wondering if I could have some help with this NumberFormatException with code using a text input.
The result should be it being able to run properly and be able to first put 50 strings into the hashTable and then remove 10 afterwards.
I have tried placing the removeLine.next() inside a String datatype and then placing the String back inside the Integer.parseInt which didn't work.
Here is the class:
import java.io.*;
import java.util.*;
public class hashTest {
public static void main(String args[]) throws FileNotFoundException {
HashTable hashTable = new HashTable();
Scanner insert = new Scanner(new File("data1.txt"));
while(insert.hasNext()) {
String line = insert.nextLine();
Scanner insertLine = new Scanner(line);
insertLine.next();
insertLine.next();
int index = Integer.parseInt(insertLine.next());
String data = insertLine.nextLine();
hashTable.put(index, data);
}
Scanner remove = new Scanner(new File("data2.txt"));
while(remove.hasNext()) {
String line = remove.nextLine();
Scanner removeLine = new Scanner(line);
removeLine.next();
removeLine.next();
int index = Integer.parseInt(removeLine.next());
hashTable.remove(index);
}
}
}
data1.txt :
003 : 68682774 MALIK TULLER
004 : 24248685 FRANCE COELLO
005 : 25428367 DUSTY BANNON
006 : 79430806 MELVINA CORNEJO
007 : 98698743 MALIA HOGSTRUM
008 : 20316453 TOMASA POWANDA
009 : 39977566 CHONG MCOWEN
010 : 86770985 DUSTY CONFER
011 : 92800393 LINNIE GILMAN
012 : 31850991 WANETA DEWEES
013 : 81528001 NEAL HOLSTEGE
014 : 46531276 BRADLY BOMBACI
data2.txt :
92800393 LINNIE GILMAN
86770985 DUSTY CONFER
31850991 WANETA DEWEES
46531276 BRADLY BOMBACI
25428367 DUSTY BANNON
68682774 MALIK TULLER
18088219 PENNY JOTBLAD
48235250 KENNITH GRASSMYER
20316453 TOMASA POWANDA
54920021 TYSON COLBETH
22806858 LAVERNE WOLNIK
32244214 SHEMEKA HALLOWAY
81528001 NEAL HOLSTEGE
24248685 FRANCE COELLO
23331143 JUSTIN ADKIN
79430806 MELVINA CORNEJO
59245514 LESLEE PHIFER
64357276 SCOT PARREIRA
50725704 GENARO QUIDER
52298576 AUDIE UNCAPHER
54657809 MARTY ENOCHS
54526749 TOBI HEATLEY
24903965 ALONSO GILSTAD
84936051 DEONNA STRAZZA
62522327 AHMAD THAYER
90572271 ELIJAH METEVIER
88999386 ISMAEL ELKAN

NumberFormatExceptions with Integer.parseInt() are most often caused by attempting to read something into an int that is not actually an int. Try printing each line as it is read in. If you have a line that is not purely an int (e.g., Hello123), you will get this exception with Integer.parseInt(). A cleaner debugging method (and better coding practice) would be to catch the exception and print the problematic line. You will probably see right away what's causing the issue. When reading text input from anywhere, it's never good to assume that the data is of the format you're expecting.
When your input contains data other than the int values you need, you can read each line's values into an array and extract the proper value(s). Here's an example of how you might extract the values from a single line in your second data file. Keep in mind that this still makes assumptions about the input format and therefore, is not completely fool-proof.
try {
// Split the line by whitespace, saving the values into an array
String[] singleLineVals = someLine.split("\\s+");
// Extract the first value
int firstValue = Integer.parseInt(singleLineVals[0]);
} catch (NumberFormatException nfe) {
// Handle the exception
}

Related

Calculating the sum of values from a text file?

im trying to find the sum of the cost of all my books in my libary system from a file, could someone say where im going wrong atm. It would be great help
int sum = 0;
File Fileobject = new File ("E:\\text files for java\\BooksToImport.txt");
try {
Scanner fileReader = new Scanner (Fileobject);
// Read and display each line of the file
while(fileReader.hasNext())
{
sum+= fileReader.nextInt ( );
line = fileReader.nextLine();
System.out.println(line);
System.out.println(sum);
}
fileReader.close();
This is my data im reading:
The_Hunger_Games - Suzanne_Collins - 5 - Scholastic_Press - 9781921988752
OOP_programming - Graham_Winter - 32.50 – Oreilly - 0471974555
Harry_potter - Jk_Rowling - 10 - Bloomsbury- 9788700631625
This is the errors im getting:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at c3500948JavaProjectAssignement1.c3500948.main(c3500948.java:80)
Asumming your file has fixed format Text (no other words has - as seperator) and position for amount value here is something you can try:
text file :
book1- author1- 100 - press1- 978846521988752
book2 - author2 - 100 - press2 - 9788928465887521
book3 - author3 - 100 - press3 - 9784659219887521
book4 - author4 - 100 - press4 - 9788928465887521
book5 - author5 - 100 - press5 - 9784659219887521
book6 - author6- 100 - press 6- 9788984659887521
TestClass.java
import java.util.Scanner;
import java.io.*;
class TestClass
{
public static void main(String [] args) throws Exception
{
FileReader file = new FileReader("test.txt");
Scanner sc = new Scanner(file);
double sum = 0;
while(sc.hasNext())
{
String line = sc.nextLine();
// spit the line on - char
String [] data = line.split("-");
// Important : assuming price is always at index 2 parse and use value
sum = sum + Double.parseDouble(data[2].trim());
}
sc.close();
System.out.println("Sum is "+sum);
}
}
The first line of your file is:
The_Hunger_Games - Suzanne_Collins - 5 - Scholastic_Press - 9781921988752
The code
sum+= fileReader.nextInt ( );
expects a number thought.
Before calculating the sum you need to parse out the part of the line which is the number to be added to the sum.
Scanner.next*() reads a stream until the next delimiter (the default is defined in Character.isWhitespace). When you call nextInt() it reads the next delimiter and then attempts to parse it as an int, if it is not then you get an InputMixmatchException. You can define your own delimiter like this (using an escaped regegex for <space>-<space>):
new Scanner(input).useDelimiter("\\s-\\s");
Then you would need to call .next() to skip over the parts of each line that you aren't parsing.
Now that last line of your example shows a hyphen directly following the publisher (without space). This fix might require more work over more data (such as book titles with hyphens in them). Hopefully, this gets you unstuck.

making an encryption program and im getting a sytnax error but i dont know why

Currently i'm trying to make a basic program that takes an input of any string such as a sentence or a paragraph and it takes each letter and turns it into a 3 character code once i get this working i'm assuming i should just be able to do the reverse and have it take the 3 digit code and turn it back to text, anyway i'm getting an error when i try to compile the program to test it. i have the issue marked below. also once i get the program working i would like to make a gui for it where you put in the input and it shows the out put after you click a button but as i am just starting out that seems a but advanced for me if you know any good tutorials for it please let me know!
import java.util.Scanner;
import java.util.*;
class test {
private static Scanner inp;
public static void main(String[] args) {
Map <Character, String> encryptionMappings = new HashMap<>();
encryptionMappings.put('a',"{qaz}");
encryptionMappings.put('b',"{wsx}");
encryptionMappings.put('c',"{edc}");
encryptionMappings.put('d',"{rfv}");
encryptionMappings.put('e',"{tgb}");
encryptionMappings.put('f',"{yhn}");
encryptionMappings.put('g',"{ujm}");
encryptionMappings.put('h',"{ik,}");
encryptionMappings.put('i',"{ol>}");
encryptionMappings.put('j',"{p;?}");
encryptionMappings.put('k',"{[']}");
encryptionMappings.put('l',"{qwe}");
encryptionMappings.put('m',"{asd}");
encryptionMappings.put('n',"{zxc}");
encryptionMappings.put('o',"{rty}");
encryptionMappings.put('p',"{fgh}");
encryptionMappings.put('q',"{vbn}");
encryptionMappings.put('r',"{yui}");
encryptionMappings.put('s',"{hjk}");
encryptionMappings.put('t',"{nm,}");
encryptionMappings.put('u',"{iop}");
encryptionMappings.put('v',"{qaw}");
encryptionMappings.put('w',"{sxz}");
encryptionMappings.put('x',"{red}");
encryptionMappings.put('y',"{cvf}");
encryptionMappings.put('z',"{ytg}");
encryptionMappings.put('A',"{hnb}");
encryptionMappings.put('B',"{iuj}");
encryptionMappings.put('C',"{kml}");
encryptionMappings.put('D',"{opl}");
encryptionMappings.put('E',"{wom}");
encryptionMappings.put('F',"{wsv}");
encryptionMappings.put('G',"{ths}");
encryptionMappings.put('H',"{imv}");
encryptionMappings.put('I',"{ybf}");
encryptionMappings.put('J',"{cja}");
encryptionMappings.put('K',"{thw}");
encryptionMappings.put('L',"{maz}");
encryptionMappings.put('M',"{pqa}");
encryptionMappings.put('N',"{zwl}");
encryptionMappings.put('O',"{;ld}");
encryptionMappings.put('P',"{'d;}");
encryptionMappings.put('Q',"{;ny}");
encryptionMappings.put('R',"{;ws}");
encryptionMappings.put('S',"{c/.}");
encryptionMappings.put('T',"{%#^}");
encryptionMappings.put('U',"{/mc}");
encryptionMappings.put('V',"{uka}");
encryptionMappings.put('W',"{zby}");
encryptionMappings.put('X',"{&hd}");
encryptionMappings.put('Y',"{&hw}");
encryptionMappings.put('Z',"{^#^}");
encryptionMappings.put('0',"{$g%}");
encryptionMappings.put('1',"{^#%}");
encryptionMappings.put('2',"{142}");
encryptionMappings.put('3',"{243}");
encryptionMappings.put('4',"{089}");
encryptionMappings.put('5',"{756}");
encryptionMappings.put('6',"{423}");
encryptionMappings.put('7',"{312}");
encryptionMappings.put('8',"{145}");
encryptionMappings.put('9',"{187}");
encryptionMappings.put('~',"{)*(}");
encryptionMappings.put('`',"{$#%}");
encryptionMappings.put('!',"{!^#}");
encryptionMappings.put('#',"{#^&}");
encryptionMappings.put('#',"{^#&}");
encryptionMappings.put('$',"{!?*}");
encryptionMappings.put('%',"{^<+}");
encryptionMappings.put('^',"{+$$}");
encryptionMappings.put('&',"{!!*}");
encryptionMappings.put('*',"{((%}");
encryptionMappings.put('(',"{*&^}");
encryptionMappings.put(')',"{$%^}");
encryptionMappings.put('_',"{&#^}");
encryptionMappings.put('-',"{<>?}");
encryptionMappings.put('=',"{:'^}");
encryptionMappings.put('{',"{%%G}");
encryptionMappings.put('}',"{$$$}");
encryptionMappings.put('[',"{***}");
encryptionMappings.put(']',"{:::}");
encryptionMappings.put(':',"{#$%}");
encryptionMappings.put('|',"{?H*}");
encryptionMappings.put(';',"{B&&}");
encryptionMappings.put('"',"{#gs}");
encryptionMappings.put('?',"{^gl}");
encryptionMappings.put('/',"{#gn}");
encryptionMappings.put('<',"{%TG}");
encryptionMappings.put('>',"{5%5}");
encryptionMappings.put(',',"{yty}");
encryptionMappings.put('.',"{ggg}");
inp = new Scanner(System.in);
System.out.println("Input Password");
int n = inp.nextInt();
if(n!=234) {
System.out.println("Denied Acess");
} else {
System.out.print("Password Accepted"
+ " ");
System.out.print("Input Text to encrypt: ");
String m = inp.next();
String encryptMe = "He";
StringBuilder builder = new StringBuilder();
The below line is the one that shows a syntax error for "toCharArray" i'm not sure why, I just started learning java so if its something simple that i'm missing i'm sorry, any and all help is apreciated.
for (Character c : encryptMe.toCharArray) {
builder.append(encryptionMappings.get(c));
}
String encrypted = builder.toString();
}
}
You are trying to call a method on the object but you are missing the empty () that need to follow toCharArray. Some languages allow you to omit the empty parentheses, but Java is not one of them. You should use:
for (Character c : encryptMe.toCharArray()) {
builder.append(encryptionMappings.get(c));
}
A good IDE (Eclipse, Intellij IDEA, Netbeans, etc.) will help you catch these syntax errors as you learn.

Read tab delimited file and ignore empty space

I am working on a simple project in which a tab delimited text file is read into a program.
My problem:
When reading the text file there are regularly empty data spaces. This lack of data is causing an unexpected output. For lines that do not have data in the token[4] position all data read is ignored and "4" is displayed when I run a System.out.println(Just a test that the data is being read properly). When I incorporate a value in the token[4] position the data reads fine. It is not acceptable that I input a value in the token[4] position. See below for file and code.
2014 Employee Edward Rodrigo 6500
2014 Salesman Patricia Capola 5600 5000000
2014 Executive Suzy Allen 10000 55
2015 Executive James McHale 12500 49
2015 Employee Bernie Johnson 5500
2014 Salesman David Branch 6700 2000000
2015 Salesman Jonathan Stein 4600 300000
2014 Executive Michael Largo 17000 50
2015 Employee Kevin Bolden 9200
2015 Employee Thomas Sullivan 6250
My code is:
// Imports are here
import java.io.*;
import java.util.*;
public class EmployeeData {
public static void main(String[] args) throws IOException {
// Initialize variables
String FILE = "employees.txt"; // Constant for file name to be read
ArrayList<Employee> emp2014; // Array list for 2014 employees
ArrayList<Employee> emp2015; // Array list for 2015 employees
Scanner scan;
// Try statement for error handling
try {
scan = new Scanner(new BufferedReader(new FileReader(FILE)));
emp2014 = new ArrayList();
emp2015 = new ArrayList();
// While loop to read FILE
while (scan.hasNextLine()) {
String l = scan.nextLine();
String[] token = l.split("\t");
try {
String year = token[0];
String type = token[1];
String name = token[2];
String monthly = token[3];
String bonus = token[4];
System.out.println(year + " " + type + " " + name + " " + monthly + " " + bonus);
} catch (Exception a) {
System.out.println(a.getMessage());
}
}
} catch(Exception b) {
System.out.println(b.getMessage());
}
}
}
The output I receive for lines with "Employee" returns in an unexpected way.
Output:
run:
4
2014 Salesman Patricia Capola 5600 5000000
2014 Executive Suzy Allen 10000 55
2015 Executive James McHale 12500 49
4
2014 Salesman David Branch 6700 2000000
2015 Salesman Jonathan Stein 4600 300000
2014 Executive Michael Largo 17000 50
4
4
BUILD SUCCESSFUL (total time: 0 seconds)
I tried to use an if-then to test for null value in token[4] position but that didn't really help me. I've done quite a bit of searching with no success.
I am still very new to the programming world, so please pardon my coding inefficiencies. Any support and general feedback to improve my skills is greatly appreciated!
Thank you,
Bryan
Java Devil is right that the underlying issue because of an ArrayOutOfBoundsException. But it's also worth exploring why you didn't see that. As we discussed in the comments your "Try statement for error handling" is in fact not handling your errors at all, instead it is suppressing them, which is generally a poor plan as it allows your program to continue running even after your assumption (that it works correctly) has been violated.
Here's a slightly cleaned up version of your code. The underlying problem that causes the ArrayOutOfBoundsException is still there, but the issue would be immediately apparent if you'd structured your code this way instead. There's a few comments calling out issues inline.
public class EmployeeData {
// constants should be declared static and final, and not inside main
private static final String FILE = "employees.txt";
// If you have an exception and you don't know how to handle it the best thing
// to do is throw it higher and let the caller of your method decide what to do.
// If there's *nothing* you want to do with an exception allow main() to throw
// it as you do here; your program will crash, but that's a good thing!
public static void main(String[] args) throws IOException {
// Notice the <> after ArrayList - without it you're defining a "raw type"
// which is bad - https://stackoverflow.com/q/2770321/113632
ArrayList<Employee> emp2014 = new ArrayList<>();
ArrayList<Employee> emp2015 = new ArrayList<>();
// A try-with-resources block automatically closes the file once you exit the block
// https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
try (Scanner scan = new Scanner(new BufferedReader(new FileReader(FILE)))) {
while (scan.hasNextLine()) {
String l = scan.nextLine();
String[] token = l.split("\t");
// The code below this line assumes that token has at least five indicies;
// since that isn't always true you need to handle that edge case before
// accessing the array indicies directly.
String year = token[0];
String type = token[1];
String name = token[2];
String monthly = token[3];
String bonus = token[4];
System.out.println(year + " " + type + " " + name + " " + monthly + " " + bonus);
}
}
}
}
This is happening because you are actually getting an ArrayOutOfBoundsException and the message for that is '4'. Because the index of 4 is greater than the length of the array. You should put in your catch statement b.printStackTrace() as this will give you greater details when ever the caught exception occurs.
You can get around this by adding the following:
String bonus = "";
if(token.length > 4)
bonus = token[4];

How can i avoid this format exception despite trim

EDIT : hidden character mess'd with my editor.
I want to read from my text file and add objects to an array from it. I'm getting a
NumberFormatException: For input string : "2".
If I remove the first line of the file, I get a format exception for input string "3".
What am I missing there ?
ArrayList<Personne> listp = new ArrayList<Personne>();
try {
FileReader file = new FileReader(personneFilePath);
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String line = sc.nextLine();
String[] attributes = line.split(",");
listp.add(new Personne(Integer.parseInt(attributes[0].trim()), attributes[1], attributes[2], Double.parseDouble(attributes[3]), attributes[4], attributes[5], attributes[6]));
}
file.close();
} catch (FileNotFoundException e) {
System.out.println("Erreur 1 : " + e.getMessage());
} catch (IOException e) {
System.out.println("Erreur 2 : " + e.getMessage());
}
Here is the content of the file i'm reading;
2, Claire, Chazal, 65.0 , rue de Rennes, Laval, 53000
3, Jacques, Dupont, 90.0 , rue des Anges, Paris, 75000
4, Celine, Dia, 66.0 , rue Diderot, Paris, 75000
5, Remy, Cheval, 88.0 , rue du paradis, Nantes, 44000
It loosk like your file contains some unprintable characters near 2 which is not whitespace so trim() can't remove it.
To remove it you can use replaceAll("\\D","") instead of trim().
Better preferred solution would be removing cause of this problem, so set up your editor/file format/encoding properly and stop placing these characters in your file.
What you are doing looks fine.
I would recommend using debug mode (IntelliJ or Eclipse work well for this) and stepping into the Integer.parseInt method to see what input it is getting or where it fails.
Alternatively, add a print statement to see the value of attributes[0].trim(), maybe also the length of the string. It seems like there may be a non-printable character.

Weird BufferedReader behavior for a huge file

I am getting a very weird error. So, my program read a csv file.
Whenever it comes to this line:
"275081";"cernusco astreet, milan, italy";NULL
I get an error:
In the debug screen, I see that the BufferedReader read only
"275081";"cernusco as
That is a part of the line. But, it should read all of the line.
What bugs me the most is when I simply remove that line out of the csv file, the bug disappear! The program runs without any problem. I can remove the line, maybe it is a bad input or whatever; but, I want to understand why I am having this problem.
For better understanding, I will include a part of my code here:
reader = new BufferedReader(new FileReader(userFile));
reader.readLine(); // skip first line
while ((line = reader.readLine()) != null) {
String[] fields = line.split("\";\"");
int id = Integer.parseInt(stripPunctionMark(fields[0]));
String location = fields[1];
if (location.contains("\";")) { // When there is no age. The data is represented as "location";NULL. We cannot split for ";" here. So check for "; and split.
location = location.split("\";")[0];
System.out.printf("Added %d at %s\n", id, location);
people.put(id, new Person(id, location));
numberOfPeople++;
}
else {
int age = Integer.parseInt(stripPunctionMark(fields[2]));
people.put(id, new Person(id, location, age));
System.out.printf("Added %d at: %s age: %d \n", id, location, age);
numberOfPeople++;
}
Also, you can find the csv file here or here is a short version of the part that I encountered the error:
"275078";"el paso, texas, usa";"62"
"275079";"istanbul, eurasia, turkey";"26"
"275080";"madrid, n/a, spain";"29"
"275081";"cernusco astreet, milan, italy";NULL
"275082";"hacienda heights, california, usa";"16"
"275083";"cedar rapids, iowa, usa";"22"
This has nothing whatsoever to do with BufferedReader. It doesn't even appear in the stack trace.
It has to do with your failure to check the result and length of the array returned by String.split(). Instead you are just assuming the input is well-formed, with at least three columns in each row, and you have no defences if it isn't.

Categories