Values Not Being Read in Correctly From File - java

I am trying to read in x,y coordinates in from a file separated by a comma. However, the elements are not being added to the ArrayList properly. Where am I going wrong here?
ArrayList<Double> xpointArrayList = new ArrayList<Double>();
ArrayList<Double> ypointArrayList = new ArrayList<Double>();
try {
BufferedReader input = new BufferedReader(new FileReader(args[0]));
String line;
while ((line = input.readLine()) != null) {
line = input.readLine();
String[] splitLine = line.split(",");
double xValue = Double.parseDouble(splitLine[0]);
double yValue = Double.parseDouble(splitLine[1]);
xpointArrayList.add(xValue);
ypointArrayList.add(yValue);
}
input.close();
} catch (IOException e) {
} catch (NullPointerException npe) {
}
double[] xpoints = new double[xpointArrayList.size()];
for (int i = 0; i < xpoints.length; i++) {
xpoints[i] = xpointArrayList.get(i);
}
double[] ypoints = new double[ypointArrayList.size()];
for (int i = 0; i < ypoints.length; i++) {
ypoints[i] = ypointArrayList.get(i);
}
When I do the Array.toSring call on the xpoints and the ypoints array. It only has one number. For example in the file:
1,2
3,4
0,5
It only has 3.0 for the xpoints array and 4.0 for the ypoints array. Where is it going wrong?

while ((line = input.readLine()) != null) {
line = input.readLine();
You just read a line, discarded it, then read another line.
Rinse, repeat (since it's a loop).
In the future, you really should think about using the debugger. You can step through your code as it executes and see exactly what is going on. Learning to use it will be invaluable.
Edit To add: As GregHaskins points out the comments below, you also obscured the problem by catching the NullPointerException and not acting on it. On the second iteration of your loop, line would be null on the second call to readLine() because there was nothing left in the file. The call to split() then throws a NullPointerException which you catch ... then silently ignore.

You can also read input using the Scanner class. The following is a modified version of your code using the Scanner and File classes to read the File:
ArrayList<Double> xpointArrayList = new ArrayList<Double>();
ArrayList<Double> ypointArrayList = new ArrayList<Double>();
try {
Scanner input = new Scanner(new File("testing.txt"));
String line;
while (input.hasNextLine()) {
line = input.nextLine();
String[] splitLine = line.split(",");
double xValue = Double.parseDouble(splitLine[0]);
double yValue = Double.parseDouble(splitLine[1]);
xpointArrayList.add(xValue);
ypointArrayList.add(yValue);
}
input.close();
} catch (IOException e) {
} catch (NullPointerException npe) {
}
double[] xpoints = new double[xpointArrayList.size()];
for (int i = 0; i < xpoints.length; i++) {
xpoints[i] = xpointArrayList.get(i);
}
double[] ypoints = new double[ypointArrayList.size()];
for (int i = 0; i < ypoints.length; i++) {
ypoints[i] = ypointArrayList.get(i);
}

Your reading style is not right. You are calling the readLine() two times. One at the top and other just after entering the while() loop. This way u are not processing all the points. Some point coordinates are getting ignored.
You should use.
while ((line = input.readLine()) != null) {
//line = input.readLine(); */Remove this */
*/your code */
}

Related

Filling a double[][] from the CSV file

I have this CSV file:
World Development Indicators
Number of countries,4
Country Name,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014
Bangladesh,6.28776238,13.20573922,23.46762823,30.16828408,34.35334451,44.94535882,55.19256723,62.82023906,74.42964608,80.03535051
"Bahamas, The",69.21279415,75.37855087,109.340767,102.7875065,101.2186453,118.8292307,81.5628489,80.65383375,76.05187427,82.29635806
Brazil,46.31418452,53.11025849,63.67475185,78.5549801,87.54187651,100.8810115,119.0023853,125.0018521,135.3050481,138.9514906
Germany,94.55486999,102.2828888,115.1403608,126.5575074,126.2280577,106.4836959,109.6595675,111.5940398,120.9211651,120.4201855
I am trying to store countries' data(double once) into a matrix(double[][]). Here is the code that I have so far:
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
String row;
int indexRow = 0;
int indexColumn = 0;
BufferedReader br = new BufferedReader(new FileReader(fileName));
br.readLine();
br.readLine();
String line = br.readLine();
while(line != null && !line.isEmpty()){
line = br.readLine();
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
for(int i = 1; i < array.length; i++){
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
}
System.out.print(Arrays.deepToString(table));
return table;
}
I am getting an arror : NullPointerException at:
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
I cant figure out why. I tried different combinations. nothing seems to work. It seems to pick up the numbers from the CSV file and store them, but when I call:
System.out.print(Arrays.deepToString(table));
it does not print out anything, hence I cant check if its stored properly or not. Could you tell me: 1. Why I am getting an error. 2. Why System.out.println does not print out an array. Thanks
If we assume that name of a country will not contain a digit and country name and numbers will be only comma separated, then following can be done without regex. I have changed file reading a little bit because it can run into issues.
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
int indexRow = 0;
int indexColumn = 0;
BufferedReader br = new BufferedReader(new FileReader(fileName));
br.readLine(); // ignore first line
br.readLine(); // ignore second line
br.readLine(); // ignore third line (contains title)
String line;
while (true) {
line = br.readLine();
if (line == null) break; // end of file reading
int index = 0;
while (true) {
index = line.indexOf(",", index) + 1;
if (Character.isDigit(line.charAt(index))) {
break;
}
}
// from index, line is expected to contain comma separated numbers
String[] array = line.substring(index).split(",");
for (int i = 0; i < array.length; i++) {
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
}
System.out.print(Arrays.deepToString(table));
return table;
}
In the csv, first 3 lines are not real country's data. So read in line-4 before while loop starts.
In while loop, first finish the processing of line string first. Eg: regular expression check & assign split data into table.
Then only read in next line at end of while loop, to be processed in next iteration.
Feel free to try this out:
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
int indexRow = 0;
int indexColumn = 0;
// check whether you need to handle any exception for this
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = null;
try {
// line 1-3 are not real country's data
br.readLine();
br.readLine();
br.readLine();
// first country data begin at line 4
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
while (line != null && !line.isEmpty()) {
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
for (int i = 1; i < array.length; i++) {
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
// read next line only at end of loop, not beginning of loop
// line is ready to be processed at next iteration
try {
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.print(Arrays.deepToString(table));
return table;
}
Arrays.deepToString is wrong. You are passing in an array of primitives. When you pass it in, you pass in double[][]. This is interpeted as Object[] where the objects are double[], so it will try to print double[] objects, and not print doubles.
One solution is to create an array Double[][].
Change
double[][] table = new double[4][10];
to
Double[][] table = new Double[4][10];
Autoboxing will convert each double to a Double. Since Double is an object and not a primitive, deepToString will print out each Double individually. If you read the javadoc for deepToString it explains that it operates recursively on arrays of reference type, not on primitive arrays.
If you want to stick with double[][]
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
System.out.print(table[i][j]);
System.out.print(' ');
}
System.out.println();
}

Reading a text file into a 2D array

I need to read a text file into a 2D array, I can read files into the program perfectly fine (see my code below) however I cannot get my head around how to read them into a 2D array. The array the function is reading into is a global array hence why it's not in the function.
Also I won't know the amount of rows the array has at first (currently set at 300 as it won't be over this) and I know this could cause a problem, I've seen some people suggest using ArrayLists however I have to have a 2D array so I was also wondering if there was a way to change an ArrayList to a 2D array and if this would be more effective?
public static String readMaze(String fileName) {
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
for (int i = 0; i < mazeNew.length; i++) {
for (int j = 0; j < mazeNew[i].length; j++) {
// mazeNew[i][j] = ; - this is where I think something needs to be added
}
}
}
bufferedReader.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file: " + fileName);
}
catch (IOException ex) {
System.out.println("Error reading file: " + fileName);
}
return fileName;
}
example text file:
11 4
5 6
4 6
0 5
3 5
8 7
1 4
There's a few options here, but generally you'll want to use the Java Scanner class as it's designed for exactly this kind of thing. Alternatively, use an existing structured data format (like JSON or XML) and an existing parser to go with it - the advantage being you can make use of a vast amount of tools and libraries which deal with those formats and don't have to re-invent anything.
However, following through with the scanner approach, it would be like so:
public static ArrayList<int[]> readMaze(String fileName) {
// Number of ints per line:
int width=2;
// This will be the output - a list of rows, each with 'width' entries:
ArrayList<int[]> results=new ArrayList<int[]>();
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
Scanner mazeRunner = new Scanner(bufferedReader);
// While we've got another line..
while (mazeRunner.hasNextLine()) {
// Setup current row:
int[] row = new int[width];
// For each number..
for (int i = 0; i < width; i++) {
// Read the number and add it to the current row:
row[i] = mazeRunner.nextInt();
}
// Add the row to the results:
results.add(row);
// Go to the next line (optional, but helps deal with erroneous input files):
if ( mazeRunner.hasNextLine() ) {
// Go to the next line:
mazeRunner.nextLine();
}
}
mazeRunner.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file: " + fileName);
}
catch (IOException ex) {
System.out.println("Error reading file: " + fileName);
}
return results;
}
If you have fixed no. of columns you can use this, but make sure input file must follow the same no of coulmns.
FileReader fileReader = new FileReader(fileName);
Scanner sc = new Scanner(fileReader);
int row=0, col=0;
while ((sc.hasNext()) != null) {
if(col < colSize){ //colSize is size of column
mazeNew[row][col]= sc.nextInt();
}
else{
col=0;
row++;
}
}
Below is the core logic, you would probably also like to to handle some errors, such as how many elements is a line split into, are there empty lines, etc.
List<String[]> list = new ArrayList<>();
Pattern pattern = Pattern.compile("\\s+");
while ((line = bufferedReader.readLine()) != null) {
list.add(pattern.split(line, -1));
}
String[][] mazeNew = list.toArray(new String[0][0]);
Something like this would work
it wont only read 2d text files .. it should work fine with any dimensions
public class Utile{
public static ArrayList<int[]> readMaze(String path){
ArrayList<int[]> result = new ArrayList<>();
try{
Scanner sc = new Scanner(new File(path));
String[] temp;
String line;
while(sc.hasNextLine()){
line = sc.nextLine();
if (line.length() != 0){ //if the line is empty it will cause NumberFormatException
temp = line.split(" ");
int[] val = new int[temp.length];
for(int i = 0;i < temp.length;i++){
val[i] = Integer.pareseInt(temp[i]);
}
result.add(val);
}
}
sc.close();
}catch(Exception e){
e.printStackTrace(); //just log it for now
}
return result;
}
}
I am not a java expert, but in PHP I would do it with explode(). But I found an example how to do the same in java using string.split(). The result is the same ... an 2D Array of the content. If possible you should try to add an delimiter to the rows inside that text document. But you could split the rows on the space character either.
Example:
String foo = "This,that,other";
String[] split = foo.split(",");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < split.length; i++) {
sb.append(split[i]);
if (i != split.length - 1) {
sb.append(" ");
}
}
String joined = sb.toString();

How to read a file in Java and save each item

I have a text file with integers and double number like this:
16 -122.454803 41.923870
17 -122.440536 41.946377
18 -122.440498 41.956013
I have 3 lists(one int and two double lists) and i want to save the items from each column. How can i split the items and save them in the lists?
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Double> list2 = new ArrayList<Double>();
ArrayList<Double> list3 = new ArrayList<Double>();
BufferedReader in = new BufferedReader(new FileReader("Nodes.txt"));
String line;
while((line = in.readLine()) != null){
list1.setNodeId(line.split(" "));
System.out.println(line);
}
in.close();
One way to process the data:
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(" ");
if (parts.length != 3) {
continue;
}
list1.add(Integer.parseInt(parts[0]));
list2.add(Double.parseDouble(parts[1]));
list3.add(Double.parseDouble(parts[2]));
}
However: this code lacks error checking on the data type. And I guess you need to process the data afterwards, so I highly suggest that you write a GeoPosition class (just a name guess from the data) with the index and position fields and a parse(String) method to parse each line. A list of such elements is much easier to process afterwards in comparison to 3 separate lists.
You can do something like this:
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Double> list2 = new ArrayList<Double>();
ArrayList<Double> list3 = new ArrayList<Double>();
BufferedReader in;
String line;
try {
in = new BufferedReader(new FileReader("Nodes.txt"));
while((line = in.readLine()) != null){
System.out.println(line);
String arr[] = line.split(" ");
list1.add(Integer.valueOf(arr[0]));
list2.add(Double.valueOf(arr[1]));
list3.add(Double.valueOf(arr[2]));
}
in.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < list1.size(); i++){
System.out.println(list1.get(i));
}
for (int i = 0; i < list2.size(); i++){
System.out.println(list2.get(i));
}
for (int i = 0; i < list3.size(); i++){
System.out.println(list3.get(i));
}
}
String.split returns an array of Strings. You need to take appropriate array entry and convert it to desired value type
String[] entries = line.split(" ");
list1.add(Integer.valueOf(entries[0]));
list2.add(Double.valueOf(entries[1]));
list3.add(Double.valueOf(entries[2]));
You can try by this way ;)
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Double> list2 = new ArrayList<Double>();
ArrayList<Double> list3 = new ArrayList<Double>();
Path path = Paths.get("C:/User/.../.../.../nodes.txt");
Scanner in = new Scanner(path);
double line;
while(in.hasNextDouble()){
line = in.nextDouble();
list1.add((int)line);
line = in.nextDouble();
list2.add(line);
line = in.nextDouble();
list3.add(line);
System.out.println(line);
}
in.close();
Don't forget to write the correct path, and tell if it's working ;)
edit : be careful, i tried and "15.05" is not working with my method, it needs "15,05", i think it will be the same with the post just over mine

Parsing text file to jagged array

I have the following file
3
2,3,4,5
6,7,8
9,10
and I am trying to convert it to pass it as jagged array of double. By that I mean, I am trying to store this as
double[][] myArray = {{2,3,4},{6,7},{9}}
double[] secondArray = {5,8,10}
I have been able to get the values read from the file but I am stuck on 2 things.
How can I convert the values into double array?
How can I store the last elements into a new array?
I am facing the error because my array contains comma separated values but how can I get the individual values to convert to double? I am still new to Java so I am not aware of all the inbuilt methods.
here is what I have so far
public double[] fileParser(String filename) {
File textFile = new File(filename);
String firstLine = null;
String secondLine = null;
String[] secondLineTokens = null;
FileInputStream fstream = null;
try {
fstream = new FileInputStream(filename);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
try {
firstLine = br.readLine(); // reads the first line
List<String> myList = new ArrayList<String>();
while((secondLine = br.readLine()) != null){
myList.add(secondLine);
//secondLineTokens = secondLine.split(",");
}
String[] linesArray = myList.toArray(new String[myList.size()]);
for(int i = 0; i<linesArray.length; i++){
System.out.println("tokens are: " + linesArray[i]);
}
double[] arrDouble = new double[linesArray.length];
for(int i=0; i<linesArray.length; i++)
{
arrDouble[i] = Double.parseDouble(linesArray[i]); #error here
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
It looks like the first line gives you the number of lines in the rest of the file. You can leverage it to make the arrays upfront, like this:
int n = Integer.parseInt(br.readLine());
double a[][] = new double[n][];
double b[] = new double[n];
for (int i = 0 ; i != n ; i++) {
String[] tok = br.readLine().split(",");
a[i] = new double[tok.length-1];
for (int j = 0 ; j != a[i].length ; j++) {
a[i][j] = Double.parseDouble(tok[j]);
}
b[i] = Double.parseDouble(tok[tok.length-1]);
}
Similarly, you can use String.split method to find out how many entries is to be added to the jagged array. This way the code becomes much shorter, because you can pre-allocate all your arrays.
Demo.

Txt file into a double 2d array

I am trying to read a txt file into a array of doubles. I am using the following code which reads every line of the file:
String fileName="myFile.txt";
try{
//Create object of FileReader
FileReader inputFile = new FileReader(fileName);
//Instantiate the BufferedReader Class
BufferedReader bufferReader = new BufferedReader(inputFile);
//Variable to hold the one line data
String line;
// Read file line by line and print on the console
while ((line = bufferReader.readLine()) != null) {
System.out.println(line);
}
//Close the buffer reader
bufferReader.close();
}catch(Exception e){
System.out.println("Error while reading file line by line:"
+ e.getMessage());
}
However I want to store the txt file into a 2d double array.
I ve tried the above to load also the dimension of the txt. But I am having problems with the exceptions catch (NoSuchElementException e), it seems that it couldnt read the file.
try {
while (input.hasNext()) {
count++;
if (count == 1) {
row = input.nextInt();
r = row;
System.out.println(row);
continue;
} else if (count == 2) {
col = input.nextInt();
System.out.println(col);
c = col;
continue;
} else {
output_matrix = new double[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
String el = input.next();
Double temp = Double.valueOf(el);
double number = temp.doubleValue();
//output_matrix[i][j] = el;
output_matrix[i][j] = number;
//System.out.print(output_matrix[i][j]+" ");
}
//System.out.println();
}
}
}
} catch (NoSuchElementException e) {
System.err.println("Sfalma kata ti tropopoisisi toy arxeioy");
System.err.println(e.getMessage()); //emfanisi tou minimatos sfalmatos
input.close();
System.exit(0);
} catch (IllegalStateException e) {
System.err.println("Sfalma kata ti anagnosi toy arxeioy");
System.exit(0);
}
You might want to be using the Scanner class for it, especially the Scanner.nextDouble() method.
Also, if you don't know in advance the dimensions of the array - I'd suggest using an ArrayList instead of a regular array.
Code example:
ArrayList<ArrayList<Double>> list = new ArrayList<>();
while ((line = bufferReader.readLine()) != null) {
ArrayList<Double> curr = new ArrayList<>();
Scanner sc = new Scanner(line);
while (sc.hasNextDouble()) {
curr.add(sc.nextDouble());
}
list.add(curr);
}
At firs declare a list and collect into it all read lines:
List<String> tempHistory = new ArrayList<>();
while ((line = bufferReader.readLine()) != null) {
tempHistory.add(line);
}
Then, after bufferReader.close(); convert this tempHistory list into double[][] array.
double[][] array = new double[tempHistory.size()][];
for (int i = 0; i < tempHistory.size(); i++) {
final String currentString = tempHistory.get(i);
final String[] split = currentString.split(" ");
array[i] = new double[split.length];
for (int j = 0; j < split.length; j++) {
array[i][j] = Double.parseDouble(split[j]);
}
}
It works, but as I added in comments, this is a not so good solution, and is better to use Collections instead of array.
BTW, it works even the rows lengths are different for different lines.

Categories

Resources