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.
Related
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();
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.
I have been given this question for practice and am kind of stuck on how to complete it. It basically asks us to create a program which uses a BufferedReader object to read values(55, 96, 88, 32) given in a txt file (say "s.txt") and then return the smallest value of the given values.
So far I have got two parts of the program but i'm not sure how to join them together.
import java.io.*;
class CalculateMin
{
public static void main(String[] args)
{
try {
BufferedReader br = new BufferedReader(new FileReader("grades.txt"));
int numberOfLines = 5;
String[] textInfo = new String[numberOfLines];
for (int i = 0; i < numberOfLines; i++) {
textInfo[i] = br.readLine();
}
br.close();
} catch (IOException ie) {
}
}
}
and then I have the loop which I made but i'm not sure how to implement it into the program above. Eugh I know i'm complicating things.
int[] numArray;
numArray = new int[Integer.parseInt(br.readLine())];
int smallestSoFar = numArray[0];
for (int i = 0; i < numArray.length; i++) {
if (numArray[i] < smallestSoFar) {
smallestSoFar = numArray[i];
}
}
Appreciate your help
Try this code, it iterates through the entire file comparing number from each line with the previously read lowest number-
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader("grades.txt"));
String line;
int lowestNumber = Integer.MAX_VALUE;
int number;
while ((line = br.readLine()) != null) {
try {
number = Integer.parseInt(line);
lowestNumber = number < lowestNumber ? number : lowestNumber;
} catch (NumberFormatException ex) {
// print the error saying that the line does not contain a number
}
}
br.close();
System.out.println("Lowest number is " + lowestNumber);
} catch (IOException ie) {
// print the exception
}
}
I previously asked a question about converting a CSV file to 2D array in java. I completely rewrote my code and it is almost reworking. The only problem I am having now is that it is printing backwards. In other words, the columns are printing where the rows should be and vice versa. Here is my code:
int [][] board = new int [25][25];
String line = null;
BufferedReader stream = null;
ArrayList <String> csvData = new ArrayList <String>();
stream = new BufferedReader(new FileReader(fileName));
while ((line = stream.readLine()) != null) {
String[] splitted = line.split(",");
ArrayList<String> dataLine = new ArrayList<String>(splitted.length);
for (String data : splitted)
dataLine.add(data);
csvData.addAll(dataLine);
}
int [] number = new int [csvData.size()];
for(int z = 0; z < csvData.size(); z++)
{
number[z] = Integer.parseInt(csvData.get(z));
}
for(int q = 0; q < number.length; q++)
{
System.out.println(number[q]);
}
for(int i = 0; i< number.length; i++)
{
System.out.println(number[i]);
}
for(int i=0; i<25;i++)
{
for(int j=0;j<25;j++)
{
board[i][j] = number[(j*25) + i];
}
}
Basically, the 2D array is supposed to have 25 rows and 25 columns. When reading the CSV file in, I saved it into a String ArrayList then I converted that into a single dimension int array. Any input would be appreciated. Thanks
so you want to read a CSV file in java , then you might wanna use OPEN CSV
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import au.com.bytecode.opencsv.CSVReader;
public class CsvFileReader {
public static void main(String[] args) {
try {
System.out.println("\n**** readLineByLineExample ****");
String csvFilename = "C:/Users/hussain.a/Desktop/sample.csv";
CSVReader csvReader = new CSVReader(new FileReader(csvFilename));
String[] col = null;
while ((col = csvReader.readNext()) != null)
{
System.out.println(col[0] );
//System.out.println(col[0]);
}
csvReader.close();
}
catch(ArrayIndexOutOfBoundsException ae)
{
System.out.println(ae+" : error here");
}catch (FileNotFoundException e)
{
System.out.println("asd");
e.printStackTrace();
} catch (IOException e) {
System.out.println("");
e.printStackTrace();
}
}
}
and you can get the related jar file from here
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 */
}