Java - NumberFormatException at linear search - java

I am having this issue with the NumberFormatException in my program. Basically, I am asked to read a .csv file separated by ; and it looks like this:
// Column Explanation (not in .csv file)
id; Summary; Number; Employee1; Employee2; ....... Employee7;
"1";"Sony";"1600";"Markos";"Nikos";"Antonis";"Nikolas";"Vaggelis";"Markos";"Thanasis";
"2";"HP";"1000";"Marios";"Dimitra";"Nikolia";"Spiros";"Thomas";"Kostas";"Manolis";
"3";"Dell";"1100";"Antonis";"Aggelos";"Baggelis";"Nikos";"Kuriakos";"Panagiotis";"Rafail";
"4";"Acer";"2000";"Marina";"Aggelos";"Spiros";"Marinos";"Xristos";"Antreas";"Basilis";
What I have already done is create a String 2-d array or the .csv file called temp_arr and I am asked to write a method that will run a linear search by id and return that company. So here is the thing.
At first, I thought I should convert the input key from int -> String since my temp_arr is a String and compares the strings (which at that time they would be int but read as Strings) using temp_arr[value][value2].equals(string_key). But I had a NullPointerException.
Then I thought I should better convert my Id's from the temp_arr from String -> Int and then compare with the integer key using == operand. This action returned me a NumberFormatException.
The process is this:
System.out.println("Enter id :");
Scanner input = new Scanner(System.in);
int item = input.nextInt(); // read the key which is an Integer
int id_int; // temp_arr is String and item is int, must convert ids from String -> int
for (int i = 0; i < temp_arr.length; i++)
{
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
if (id_int == item) // If the Array's Id's are == item
{
System.out.println(item+" is present at location " + (i+1) );
break;
}
if (i == temp_arr.length)
System.out.println(item + " does not exist");
}
My error appears at line 7 and I do not know why.
Read File process:
String csvFile = "sam.csv"; // .csv file to be placed in the project file!
BufferedReader br = null; // ini
String line = "",cvsSplitBy = ";"; // columns asked to be split by ";"
String[] arr = null;
String[][] temp_arr = new String[1000][10];
int temp = 0;
try
{
br = new BufferedReader(new FileReader(csvFile)); //start reading the file
while ((line = br.readLine()) != null) // while the line has words
{
arr = line.split(cvsSplitBy); // creating the array
System.out.println(arr[0] + "\t" + arr[1] + "\t" + arr[2] + "\t" + arr[3] + "\t" + arr[4] + "\t" + arr[5] + "\t" + arr[6] + "\t" + arr[7] + "\t" + arr[8] + "\t" + arr[9] );
for (int i = 0; i<=9; i++)
{
temp_arr[temp][i] = arr[i]; // temp_arr represents (is a copy of) the .csv file
}
temp++;
}
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
if (br != null)
{
try
{
br.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
System.out.println("Done!\n");
Output (Image) :
Line 106 which is causing the issue is :
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int

Your issue is that your Integer.parseInt() is trying to parse a "2" WITH QUOTATION MARKS. That's the problem.
A quick solution would be to replace this line:
temp_arr[temp][i] = arr[i];
To this:
temp_arr[temp][i] = arr[i].replaceAll("\"", "");
Anyway, I'd like to suggest using a different data structure for your case, because I've done something like this before for a client. Have you ever heard of HashMaps? You can do something like a HashMap with an int key and String[] values to store your data in, and the key can be your id_int. Maybe you can try this implementation next time. It's a lot more elegant.
Hope I was able to help!
Cheers,
Justin

Would help if you also posted some of your data file and how you are reading it in.
But, my guess from what is presented is if you add System.out.println(temp_arr[i][0]) prior to the 7th line or run this code through a debugger you will see that temp_arr[i][0] is not an integer value as that is what the error is telling you.

Related

Printing out array data stored from File read

I'm trying to create a class that uses a separate method to read and store two sets of data from a file into 2 different arrays. I don't know if it's the read method or my output that is incorrect but I can't seem to figure out how to have it printout all data sets. I get the last line of the file instead of all content.
examples from products.txt are
Product1,1100
Product2,1205
Product3,1000
Main Method
String[] pName;
double[] pPrice;
String outputStr = null;
int i = 0;
//String name = null;
// Input number of customers
//initialize arrays with size
pPrice=new double[50];
pName=new String[50];
// read from file, the method is incomplete
try {
readFromFile(pName, pPrice, "products.txt");
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "File cannot be read");
e.printStackTrace();
}
for (i = 0; i < pName.length; i++) {
outputStr = pName[i] + "," + pPrice[i] + "\n";
}
// Call method before sorting both arrays
display(outputStr);
Reading Method
public static void readFromFile(String[] pName, double[] pPrice, String fileName) throws FileNotFoundException {
// read data from products
// Create a File instance
File file = new File(fileName);
// Create a Scanner for the file
Scanner sc = new Scanner(file);
// Read data from a file, the data fields are separated by ','
// Change the Scanner default delimiter to ','
sc.useDelimiter(",|\r\n");
// Start reading data from file using while loop
int i = 0;
while (sc.hasNext()) {
String name = sc.next();
String cost = sc.next();
//add the customer data through arrays
pName[i] = name;
pPrice[i] = Double.parseDouble(cost);
i++;
}//end while
// Close the file
The problem is that your for loop assigns every line to the outputStr variable:
for (i = 0; i < pName.length; i++) {
outputStr = pName[i] + "," + pPrice[i] + "\n";
}
Seeing your linefeed in the end I assume you want to concatenate all lines into that string variable. So change that code into
for (i = 0; i < pName.length; i++) {
outputStr += pName[i] + "," + pPrice[i] + "\n";
}
As you initialize the variable to be null this may throw a NullPointerException. If that is the case, simply initialize with "".

Why turns the string to empty?

If I run this code the first 28 lines of the append.txt are full of numbers but then it is empty, why? It should also contains some numbers!!
Is the String get too big?
try {
OutputStream os = new FileOutputStream(new File("append.txt"), true);
String seq = "11", output = "";
int u = 1;
while(u<=37)
{
String temp = "";
int iter = 1;
for(int i=0; i<seq.length()-1; i++) {
if(seq.charAt(i)==seq.charAt(i+1)) {
iter++;
if(i==seq.length()-2) {
temp += iter + "" + seq.charAt(i);
iter=1;
}
}else {
temp += iter + "" + seq.charAt(i);
if(i==seq.length()-2) {
temp += "1" + seq.charAt(i+1);
}
iter=1;
}
}
seq=temp;
output += seq + "\n";
System.out.println(u + ": " + seq.length());
u++;
}
os.write(output.getBytes(), 0, output.length());
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Ok, I have the solution:
I use Eclipse to show the text file but it magically do not show the rest of the file. If I use any other text editor it will show the rest. Maybe the eclipse txt editor can only show a limited amount of text...
If the String would be too big to create you would get an OutOfMemoryException. This is not the case, your program works and prints 37 lines of numbers with last line being 48410 characters long.
Most likely the editor you are using to view the output fails to render these very long lines. It works in IntelliJ IDEA for me.

Make an array of words in alphabetical order in java, after reading them from a file

I've got the following code that opens and read a file and separates it to words.
My problem is at making an array of these words in alphabetical order.
import java.io.*;
class MyMain {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Kennedy.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
int line_count=0;
int byte_count;
int total_byte_count=0;
int fromIndex;
while( (line = br.readLine())!= null ){
line_count++;
fromIndex=0;
String [] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
String line_rest=line;
for (int i=1; i <= tokens.length; i++) {
byte_count = line_rest.indexOf(tokens[i-1]);
//if ( tokens[i-1].length() != 0)
//System.out.println("\n(line:" + line_count + ", word:" + i + ", start_byte:" + (total_byte_count + fromIndex) + "' word_length:" + tokens[i-1].length() + ") = " + tokens[i-1]);
fromIndex = fromIndex + byte_count + 1 + tokens[i-1].length();
if (fromIndex < line.length())
line_rest = line.substring(fromIndex);
}
total_byte_count += fromIndex;
}
}
}
I would read the File with a Scanner1 (and I would prefer the File(String,String) constructor to provide the parent folder). And, you should remember to close your resources explicitly in a finally block or you might use a try-with-resources statement. Finally, for sorting you can store your words in a TreeSet in which the elements are ordered using their natural ordering2. Something like,
File file = new File("C:/", "Kennedy.txt");
try (Scanner scanner = new Scanner(file)) {
Set<String> words = new TreeSet<>();
int line_count = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
line_count++;
String[] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
Stream.of(tokens).forEach(word -> words.add(word));
}
System.out.printf("The file contains %d lines, and in alphabetical order [%s]%n",
line_count, words);
} catch (Exception e) {
e.printStackTrace();
}
1Mainly because it requires less code.
2or by a Comparator provided at set creation time
If you are storing the tokens in a String Array, use Arrays.sort() and get a naturally sorted Array. In this case as its String, you will get a sorted array of tokens.

Java StringTokenizer running out of bounds with .CSV file

I am trying to read a simple .CSV file and create a 2D array of Strings. Here is the array:
1,1,1,1,1,1
2,2,2,2,2,2
3,3,3,3,3,3
4,4,4,4,4,4
My code is supposed to find six columns and four rows, but it stops after the third column and moves on to the next row and I cannot figure out why this is happening.
In addition to this, it returns an out of bounds exception even though it quits early.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
Here is the code and it is followed by the output.
public String[][] ascToStringArray(String ascFileIn) {
String directory ="c:\\data\\"; // "\" is an illegal character
String[][] numbers= new String[4][6]; // 4 rows 6 columns
try{
BufferedReader Br = new BufferedReader(new FileReader(directory + ascFileIn));
String line;
int row = 0;
int col = 0;
//read each line of text file
while((line = Br.readLine()) != null)
{
StringTokenizer st = new StringTokenizer(line,",");
//Populating Columns
while (st.hasMoreTokens())
{
//get next token and store it in the array
numbers[row][col] = st.nextToken();
System.out.println(row + " " + col + " = " + st.nextToken());
col++;
}
row++;
}
//close the file
Br.close();
return numbers;
}
catch(IOException exc) {
System.out.println("Error reading file.");
return numbers;
}
}
Here is the output:
0 0 = 1
0 1 = 1
0 2 = 1
1 3 = 2
1 4 = 2
1 5 = 2
If anyone can figure out why it is quitting early and throwing me an out of bounds error no matter how large I make the array I would really appreciate it.
You are using nextToken twice.
numbers[row][col] = st.nextToken();<-1---
System.out.println(row + " " + col + " = " + st.nextToken());<--2--Skips element
But using only one value so in one row only three element of line will be added.
Reason of Exception
You are not resetting the col=0 after the execution of inner while loop which leads to ArrayIndexOutOfBound for col=6 as col size in array is 6 means 0 to 5 so will throw exception when col=6.
Firstly the system.out.println inside the inner while loop consumes a token.. Second on entring the inner while loop you should reset the cols files. to zero.
public String[][] ascToStringArray(String ascFileIn) {
String directory = "c:\\data\\"; // "\" is an illegal character
String[][] numbers = new String[4][6]; // 4 rows 6 columns
try {
BufferedReader Br = new BufferedReader(new FileReader(directory + ascFileIn));
String line;
int row = 0;
int col = 0;
// read each line of text file
while ((line = Br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line, ",");
col = 0;
// Populating Columns
while (st.hasMoreTokens()) {
// get next token and store it in the array
numbers[row][col] = st.nextToken();
col++;
}
row++;
}
// close the file
Br.close();
return numbers;
} catch (IOException exc) {
System.out.println("Error reading file.");
return numbers;
}
}
It's because you are calling st.nextToken() twice, swallowing an extra token in your System.out.println.
Instead, first save it into a String:
String token = st.nextToken();
then you can use the same String in your print and for the array.
http://msdn.microsoft.com/fr-fr/library/aa989865(v=vs.80).aspx
StringTokenizer.nextToken () : Gets the next token in the string
during parsing.
numbers[row][col] = st.nextToken();
System.out.println(row + " " + col + " = " + st.nextToken());
You go through your tokens without using them !

Storing a single csv object into an array

hey ive got a chunk of code thats supposed loads lines of csv file into an array of objects:
public static WarehouseItem[] loadRecords(WarehouseItem[] records) {
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
int numRows = 0;
String warehouseItem;
String filename;
filename = ConsoleInput.readLine("Please enter the filename (DataMillion.csv OR DataThousand.csv)");
try {
fileStrm = new FileInputStream(filename);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
warehouseItem = bufRdr.readLine();
records[numRows] = new WarehouseItem(warehouseItem); //NULL POINTER EXCEPTION HERE
System.out.println(records[0].toString(records[0].columnVals));
while (warehouseItem != null) {
numRows++;
records[numRows] = new WarehouseItem(warehouseItem);
warehouseItem = bufRdr.readLine();
}
fileStrm.close();
}
catch (IOException e) {
if (fileStrm != null) {
try {
fileStrm.close();
} catch (IOException ex2) {}
}
System.out.println("Error in file processing: " + e.getMessage());
}
main(null);
return records;
}
but when i run it, i get a NullPointerException on the line
records[numRows] = new WarehouseItem(warehouseItem);
is there anything that i missed??
heres the WarehouseItem constructor + toString:
public class WarehouseItem {
String[] columnVals;
int numColumns = 5;
public WarehouseItem(String warehouseItem) {
String key, brand, model, price, weightInKG;
int intWeightInKG;
double doublePrice;
StringTokenizer strTok;
strTok = new StringTokenizer(warehouseItem, ",");
key = strTok.nextToken();
brand = strTok.nextToken();
model = strTok.nextToken();
intWeightInKG = Integer.parseInt(strTok.nextToken());
doublePrice = Double.valueOf(strTok.nextToken());
weightInKG = String.valueOf(intWeightInKG);
price = String.valueOf(doublePrice);
String[] columnVals = {key, brand, model, weightInKG, price};
if(columnVals.length != 5)
throw new IllegalStateException("Invalid CSV: not enough columns");
}
public String toString(String[] columnVals) {
return ("Key: " + columnVals[0] + "\n" +
"Brand: " + columnVals[1] + "\n" +
"Model: " + columnVals[2] + "\n" +
"Weight: " + columnVals[3] + "\n" + " kg" +
"Price: " + "$" + columnVals[4] + "\n");
}
}
What my problem is the values aren't getting stored into the array records properly and im not sure why
You didn't initialize array, that was a cause NullPointerException in your code, but if you can't use array don't use it.
The number of lines might exceed the capacity of array, use List instead
List<WarehouseItem> records = new ArrayList<>();
String line = bufRdr.readLine();
while (line != null) {
WarehauseItem warehauseItem = new WarehauseItem();
records.add(warehauseItem);
warehauseItem.processLine(line);
line = bufRdr.readLine();
}
numRows = records.size();
When you create an array of objects in Java, it is initialized with all nulls. That is why you get a nullpointerexception.
So you need to create an object for each array position. In fact instead of calling a method you could just make that method a constructor; that would be simpler.
I also noticed another mistake: the method sets local variables, which only exist for the lifetime of the method, when in fact it should set instance variables.
Then I noticed a third mistake: You just caught exception, and assumed that that indicated missing columns; in fact it could indicate invalidly-typed data inside a column (e.g. string instead of integer).
You missed object creation records[numRows]=new WarehouseItem();
Your code need to be like this.
while (warehouseItem != null) {
records[numRows]=new WarehouseItem(); //here you forgot the object creation.
warehouseItem = bufRdr.readLine();
records[numRows].processLine(warehouseItem);
numRows++;
}
Because you haven't assigned anything to records[numRows]. You only defined records as an array of WarehouseItem objects.
You should assign a new WarehouseItem to that index of the array before you can use.
records[numRows] = new WarehouseItem();
warehouseItem = bufRdr.readLine();
records[numRows].processLine(wareHouseitem);

Categories