I have to read in a text file called test.txt. the first line of the text file are two integers. these integers tell you the rows and columns of the 2D char array. The rest of the file contains characters. the file looks a bit like: 4 4 FILE WITH SOME INFO except vertically on top of one another not horizontally. I must then read each of the rest of the contents of the file into the 2D char[][] array using nested for loops. I am not supposed to copy from one array to another. This is the code I have so far. I'm having trouble reading each character line by line into my 2D char array. Help been working at this for hours.
public static void main(String[] args)throws IOException
{
File inFile = new File("test.txt");
Scanner scanner = new Scanner(inFile);
String[] size = scanner.nextLine().split("\\s");
char[][] array = new char[Integer.parseInt(size[0])][Integer.parseInt(size[1])];
for(int i=0; i < 4; i++) {
array[i] = scanner.nextLine().toCharArray();
}
for(int k = 0; k < array.length; k++){
for(int s = 0; s < array[k].length; s++){
System.out.print(array[k][s] + " ");
}
System.out.println();
}
scanner.close();
}
}
If I have understood it correctly - file format is something like
4 4
FILE
WITH
SOME
INFO
Modify as below
Scanner scanner = new Scanner(inFile);
String[] size = scanner.nextLine().split("\\s");
char[][] array = new char[Integer.parseInt(size[0])][Integer.parseInt(size[1])];
for(int i=0; i < rows; i++) {
array[i] = scanner.nextLine().toCharArray();
}
Above code is for initialization of you char array. In order to print the same you can do something like
Arrays.deepToString(array);
Copying Tirath´s file format:
4 4
FILE
WITH
SOME
INFO
I would pass it into a 2d array as follows:
public static void main(String[] args){
char[][] receptor = null; //receptor 2d array
char[] lineArray = null; //receptor array for a line
FileReader fr = null;
BufferedReader br = null;
String line = " ";
try{
fr = new FileReader("test.txt");
br = new BufferedReader(fr);
line = br.readLine();//initializes line reading the first line with the index
int i = (int) (line.toCharArray()[0]-48); //we convert line to a char array and get the fist index (i) //48 = '0' at ASCII
int j = (int)(line.toCharArray()[1]-48); // ... get the second index(j)
receptor = new char[i][j]; //we can create our 2d receptor array using both index
for(i=0; i<receptor.length;i++){
line = br.readLine(); //1 line = 1 row
lineArray = line.toCharArray(); //pass line (String) to char array
for(j=0; j<receptor[0].length; j++){ //notice that we loop using the length of i=0
receptor[i][j]=lineArray[j]; //we initialize our 2d array after reading each line
}
}
}catch(IOException e){
System.out.println("I/O error");
}finally{
try {
if(fr !=null){
br.close();
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} //end try-catch-finally
}
Related
I'm trying to read a text file and put each comma separated value in an array and put all of them inside a 2d array.But the code I have right now puts the whole line in the array
Scanner sc = new Scanner(new BufferedReader(new FileReader(path)));
int rows = 3;
int columns = 1;
String[][] myArray = new String[rows][columns];
while (sc.hasNextLine()) {
for (int i = 0; i < myArray.length; i++) {
String[] line = sc.nextLine().trim().split(" " + ",");
for (int j = 0; j < line.length; j++) {
myArray[i][j] = line[j];
}
}
}
System.out.println(Arrays.deepToString(myArray));
This is the text file:
A6,A7
F2,F3
F6,G6
Output
[[A6,A7], [F2,F3], [F6,G6]]
Expected Output
[[A6],[A7],[F2],[F3],[F6],[G6]]
The problem is that you are assigning the entire 2D array instead of just each item.
Here are several alternatives.
Use Files.lines to stream the file.
splitting on a comma creates the 1D array of two elements for each line
flatMap that to stream each item.
that map that to an array of one item.
then just store them in a 2D array.
String[][] array = null;
try {
array = Files.lines(Path.of("f:/MyInfo.txt"))
.flatMap(line->Arrays.stream(line.split(","))
.map(item->new String[]{item}))
.toArray(String[][]::new);
} catch (IOException ioe) {
ioe.printStackTrace();
}
if (array != null) {
System.out.println(Arrays.deepToString(array));
}
prints
[[A6], [A7], [F2], [F3], [F6], [G6]]
Here is an approach similar to yours.
List<String[]> list = new ArrayList<>();
try {
Scanner scanner = new Scanner(new File("f:/MyInfo.txt"));
while (scanner.hasNextLine()) {
String[] arr = scanner.nextLine().split(",");
for (String item : arr) {
list.add(new String[]{item});
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
There is no deepToString for Lists so you either iterate it or convert to a 2D array.
String[][] ar = list.toArray(String[][]::new);
System.out.println(Arrays.deepToString(ar));
prints
[[A6], [A7], [F2], [F3], [F6], [G6]]
i think you have to double the rows size and for each line just put one element and increment the i++
The declaration of the result array is not correct.
Since you want the end result should look like this, [[A6],[A7],[F2],[F3],[F6],[G6]], it is a 2-dimensional array with one row and six columns.
Considering it, I have changed and simplified your code.
int rows = 3;
String[][] r = new String[1][rows * 2];
FileInputStream fstream = new FileInputStream("/path/to/the/file")
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
while((line = br.readLine()) != null) {
String[] current = line.split(",");
r[0][i++] = current[0];
r[0][i++] = current[1];
}
All the examples that i have seen involve specifying the number of rows and columns at the start of the file but the method I'm working on reads a file with the following:
1.0 2.0
3.0 4.0
and using this data creates a 2d array and stores it without specifying the number of rows and columns.
Here's the code I have written:
public static double[][] readMatrixFrom(String file) throws FileNotFoundException {
Scanner input = new Scanner(new FileReader(file));
int rows =0;
int columns =0;
while(input.hasNextLine()){
String line = input.nextLine();
rows++;
columns = line.length();
}
double[][] d = new double[rows][columns]
return d;
}
I'm unsure of how to add these values now that I have created the 2d array. i tried this but got an InputMismatchException.
Scanner s1 = new Scanner(file);
double[][] d = new double[rows][columns]
for (int i= 0;i<rows;i++) {
for (int j= 0;i<rows;j++) {
d[i][j] = s1.nextDouble();
}
}
if you just want to use the basic arrays you can achieve it with something like
Scanner input = new Scanner(new FileReader(file));
int row=0;
int col =0;
String s="";
//count number of rows
while(input.hasNextLine()) {
row++;
s=input.nextLine();
}
//count number of columns
for(char c: s.toCharArray()) {
if(c==' ')
col++;
}
col++; // since columns is one greater than the number of spaces
//close the file
input.close();
// and open it again to start reading it from the begining
input = new Scanner(new FileReader(file));
//declare a new array
double[][] d = new double[row][col];
int rowNum=0;
while(input.hasNextLine()) {
for(int i=0; i< col; i++) {
d[rowNum][i]= input.nextDouble();
}
rowNum++;
}
However if you prefer to use java collection you can avoid reading the file again. Just store the strings in a list and iterate over the list to extract elements from it.
Based on your input, Your columns = line.length(); is returning 7 rather than 2 as it returns the String length.
Hence try calculating the no of columns in the row columns = line.split(" ").length;
Also while trying to read your input you were using index i for the 2nd for-loop. It should be like below,
for (int i= 0;i<rows;i++) {
for (int j= 0;j<columns;j++) {
d[i][j] = s1.nextDouble();
}
}
In order to work with arrays of unknown size you should read the data into a Collection (such as a List). However, Collection(s) only work with the wrapper-types; so you will need to copy the elements back into an array of double(s) if that is what you really need. Something like,
public static double[][] readMatrixFrom(String file) throws FileNotFoundException {
Scanner input = new Scanner(new FileReader(file));
List<List<Double>> al = new ArrayList<>();
while (input.hasNextLine()) {
String line = input.nextLine();
List<Double> ll = new ArrayList<>();
Scanner sc = new Scanner(line);
while (sc.hasNextDouble()) {
ll.add(sc.nextDouble());
}
al.add(ll);
}
double[][] d = new double[al.size()][];
for (int i = 0; i < al.size(); i++) {
List<Double> list = al.get(i);
d[i] = new double[list.size()];
for (int j = 0; j < d[i].length; j++) {
d[i][j] = list.get(j);
}
}
return d;
}
Which I tested by creating a file in my home folder with your contents and running it like so
public static void main(String[] args) {
String file = System.getProperty("user.home") + File.separator + "temp.txt";
try {
System.out.println(Arrays.deepToString(readMatrixFrom(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
And I get (as I assume you wanted)
[[1.0, 2.0], [3.0, 4.0]]
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();
}
I'm trying to read a text file with this format:
Array x
1,3,5,4
Array y
12,13,15,11
and put it in two array, but I only want the integer.
What delimiter should I use to ignore the String and the empty line?
Here's my code in putting the int to arrays. By the way, I'm using scanner to read the file:
Scanner sc = null;
try
{
sc = new Scanner(new FileInputStream("C:\\x.txt"));
sc.useDelimiter(""); // What will I put inside a quote to get only the int values?
}
catch(Exception e)
{
System.out.println("file not found!");
}
int[] xArray = new int[4];
int[] yArray = new int[4];
while (sc.hasNextInt( )){
for(int i=0; i<4; i++){
xArray[i] = sc.nextInt( );
}
for(int i=0; i<4; i++){
yArray[i] = sc.nextInt( );
}
}
What I want to get is
int[] xArray = {1,3,5,4}
int[] yArray = {12,13,15,11}
I hope you understand :)
Thanks.
I suggest you to use bufferedreader instead of scanner. You can use below code :
BufferedReader br=new BufferedReader(new FileReader("your file name"));
br.readLine(); //it will omit first line Array x
String x=br.readLine(); //it return second line as a string
String[] x_value=x.split(","); //You can parse string array into int.
This is for Array x. You can do the same for array y. and after that parse into int.
I want to read lines of numbers from a file. The code is as follows but the IDE shows NullPointerException runtime exception. Not sure what I am doing wrong.
//reading the contents of the file into an array
public static void readAndStoreNumbers() {
//initialising the new object
arr = new int[15][];
try {
//create file reader
File f = new File("E:\\Eclipse Projects\\triangle.txt");
BufferedReader br = new BufferedReader(new FileReader(f));
//read from file
String nums;
int index = 0;
while ((nums = br.readLine()) != null) {
String[] numbers = nums.split(" ");
//store the numbers into 'arr' after converting into integers
for (int i = 0; i < arr[index].length; i++) {
arr[index][i] = Integer.parseInt(numbers[i]);
}
index++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
Your second dimension of arr is uninitialized, and you are invoking
arr[index].length
You could be running into an NPEX for two reasons.
You don't finish your definition of arr - it's not evident in your code that you declare arr as int arr[][];
Even if you had the above, you wouldn't have set aside space for your second array. What you have now is a jagged array; you can have elements of whatever length in the second dimension you wish in your second array.
The only modification I made to your code to get it to work would be the following line:
arr[index] = new int[numbers.length];
...after pulling elements into numbers, and before entering the loop.
you need to change -
for(int i=0; i<arr[index].length; i++) {
to
arr[index] = new int[numbers.length];
for (int i = 0; i < numbers.length; i++) {
Java doesn't have real multidimensional arrays. What you are using is actually an array of int arrays: new int[n][] actually creates an array with room for n objects of type int[].
Consequently you will have to initialize each of those int arrays separately. That would have been obvious from the fact that you never actually specified the length of the second dimension anywhere in your program.
I think you should use StringBuilder..
//reading the contents of the file into an array
public static void readAndStoreNumbers() {
//initialising the StringBuffer
StringBuilder sb = new StringBuilder();
try {
//create file reader
File f = new File("E:\\Eclipse Projects\\triangle.txt");
BufferedReader br = new BufferedReader(new FileReader(f));
//read from file
String nums;
int index = 0;
while ((nums = br.readLine()) != null) {
String[] numbers = nums.split(" ");
//store the numbers into 'arr' after converting into integers
for (int i = 0; i < arr[index].length; i++) {
sb.append(Integer.parseInt(numbers[i])).append("\n");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}