Reading 2D array from .txt file in java [duplicate] - java

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 2 years ago.
there is an issue in data.txt we have 4 rows and 3 cols and gives me error out of bound kindly someone solve this but when I pass 4x4 in rows and cols it works well but it didnt meet project requirement
public class ReadMagicSquare {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException {
// TODO code application logic here
Scanner sc = new Scanner(new BufferedReader(new FileReader("data.txt")));
int rows = 4;
int columns = 3;
int [][] myArray = new int[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] = Integer.parseInt(line[j]);
}
}
}
for(int i=0;i<myArray.length;i++){
for(int j=0;j<myArray.length;j++){
System.out.print(myArray[i][j]+" ");
}
System.out.println();
}
}
}
in data.txt file
2 -1 1
6 4 24
2 19 7

for(int i=0;i<myArray.length;i++){
for(int j=0;j<myArray.length;j++){
System.out.print(myArray[i][j]+" ");
}
System.out.println();
}
myArray.length gives you the number of rows in the 2D array, so in the inner loop, j would go from 0 to less than 4 instead of 0 to less than 3, which would give you an out of bound error.
You need to iterate j from 0 to the number of columns.

Here is the code where it calculates the dimensions of the matrix in the file, read it from the file and construct the matrix and prints it.
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner (new File("data.txt"));
Scanner inFile = new Scanner (new File("data.txt"));
/*To get the dimension of the matrix*/
String[] line = sc.nextLine().trim().split("\\s+");
int row = 1, column = 0;
column=line.length;
while (sc.hasNextLine()) {
row++;
sc.nextLine();
}
sc.close();
/*To read the matrix*/
int[][] matrix = new int[row][column];
for(int r=0;r<row;r++) {
for(int c=0;c<column;c++) {
if(inFile.hasNextInt()) {
matrix[r][c]=inFile.nextInt();
}
}
}
inFile.close();
/*To print the matrix*/
System.out.println(Arrays.deepToString(matrix));
}

Related

I can't get this piece of code to run. It is throwing NumberFormatException [duplicate]

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 5 years ago.
Getting NumberFormatException. What am I doing wrong here ?
I'm trying to read an array of integers separated by spaces.
Is there any other better way to do the same ? I did a lot of research and most people said that split() is better than StringTokenizer and BufferedReader.
public static void main (String args[])
{
#SuppressWarnings("resource")
Scanner io = new Scanner(System.in);
int a=io.nextInt();
String input;
for(int i=0; i<a; i++)
{
input = io.nextLine();
int x= input.length();
String[] splitArr = input.split("\\s+");
int p[]= new int[x];
int q=0;
for (String par : splitArr) {
p[q++] = Integer.parseInt(par);}
System.out.println(p);
}
}
}
Updated Code, working now:
public static void main (String args[])
{
#SuppressWarnings("resource")
Scanner io = new Scanner(System.in);
int a=io.nextInt();
io.nextLine();
String input;
for(int i=0; i<a; i++)
{
int x= io.nextInt(); //size of array
io.nextLine();
input = io.nextLine();
String[] splitArr = input.split("\\s+");
int p[]= new int[x];
int q=0;
for (String par : splitArr) {
p[q++] = Integer.parseInt(par);}
for(int m=0; m<x; m++)
System.out.print(p[m]+" ");
}
}
}
Do a io.nextLine(); (without storing it anywhere) after int a=io.nextInt(); (just before any string input that you'd want to take).
Something like
Scanner io = new Scanner(System.in);
int a=io.nextInt();
io.nextLine();
String input;
Loop through your array to get the values properly; not System.out.prinltn(p);
Try doing something like this
while(io.hasNext()){
try{
somevar = io.nextInt()
}
catch (NumberFormatException e){
//just pass through this non int value or do some error handlin
}
}

Java 2d Array unable to edit value and properly return element back null values

My knowledge with java language is very new. Most of my knowledge are from googling up on how to do things. I've been working on a console program in java that uses a switch statement. The entire program utilizes an String [20][5] array. I've written the code to now be able to add entry, save array to file, load entries from file into the array.
The problems now is edit and removing entries. I am able to return values to null but it'll look like this [[null], [null, null, null, null, null].
I want the value to return to [null, null, null, null, null], [null, null, null, null, null].
The Edit entry some reasons return an java.lang.ArrayIndexOutOfBoundsException:1 .
Could someone point out my error? Also the Array is globally declare.
public static String[][] rem(){
Scanner input = new Scanner(System.in);
int x,y=0;
//for(int i=0;i<array.length;i++){
//if(array[i][0]!=null){
System.out.println(Arrays.deepToString(array));//}
//}
System.out.println("Which entry would you like to remove? "
+ "\n" + "Enter number 0 - 20");
x = input.nextInt();
array[x][y]=null;
return array;}
public static String[][] edit(){
Scanner input = new Scanner(System.in);
String k;
int j;
int g;
// for(int i=0;i<array.length;i++){
//if(array[i][0]!=null){
//System.out.println(Arrays.deepToString(array));}
//}
System.out.println("Which entry would you like to edit? "
+ "\n" + "Enter number 0 - 20");
j = input.nextInt();
System.out.println("What would you like to edit? "
+"\n" + "Enter number 0 - 5");
g = input.nextInt();
System.out.println("You are now editing.");
k = input.next();
array[j][g] = k;
return array;}
Update
I think I figure my issue. The array properly edit values I manually input. It's when I load data into the array that causes problem because when it loads data it loads as String []. I need a code that will load the data as String[][] or as array of arrays.
public static String[][] load()throws FileNotFoundException, IOException{
menu();
copyFile();
String file = ("c:/temp/Address.txt");
Scanner scan = new Scanner(new FileReader(file));
// initialises the scanner to read the file file
//String[][] entries = new String[100][3];
// creates a 2d array with 100 rows and 3 columns.
//int i = 0;
while(scan.hasNextLine()){
array[i][i] = scan.next().split("," , "\t");
i++;
}
//loops through the file and splits on a tab
//for (int row = 0; row < array.length; row++) {
// for (int col = 0; col < array[0].length; col++) {
// if(array[row][col] != null){
// System.out.print(array[row][0] );
// }
// }
// if(array[row][0] != null){
// System.out.print("\n");
//}
// }
//prints the contents of the array that are not "null"
selectMenu();
return array;}
Update 2
I have found the solution to solving the loading data issue. The solution is simple! I'll leave the code here for reference. Though, all of the codes could use some beautifying.
public static String[][] load()throws FileNotFoundException, IOException{
menu();
copyFile();
String file = ("c:/temp/Address.txt");
Scanner scan = new Scanner(new FileReader(file));
FileReader fr = new FileReader("c:/temp/Address.txt");
BufferedReader br = new BufferedReader(fr);
//int j=0;
//int lineNo = 0;
//String line = br.readLine();
//while(line!=null)
//{
//for(int i = 0; i < 5; i++)
//{
//array[lineNo][i] = line.substring(i,4);
//}
// lineNo++;
//line = br.readLine(); // This is what was missing!
//}
//while(scan.hasNextLine()){
//while(scan.hasNext()){
//for(j=0;j<5;j++){
for(int i = 0; i < 20; ++i){
for(int j = 0; j < 5; ++j)
{
if(scan.hasNext())
{
array[i][j] = scan.next();
//i++;
//j++;
}
//i++;
}
}
selectMenu();
return array;}
Update 3
So after figuring out on how to use the delimiter it sorts of give me a weird issue. It adds return at the end of the column. [null, null, null, null, null return]. I used ",|\n" as my delimiter. Is there a better method? Update: Added a .trim(); solve the final issue with load. Now it's perfected in its current job. Though, I'm sure there might be less primitive methods.
public static String[][] load()throws FileNotFoundException, IOException{
copyFile();
//delimiter removes the comma or return to the next line. "\n" new line
Scanner scan = new Scanner(new FileReader(file)).useDelimiter(",|\n");
for(int i = 0; i < 20; ++i){
for(int j = 0; j < 5; ++j){
if(scan.hasNext())
array[i][j] = scan.next().replace(",", "").trim();
}
}
System.out.println("File loaded successfully!!");
scan.close();
return array;}
This is an off by one error, very subtle mistake:
Although you have 20 rows and 5 columns, arrays use a 0 based index(start counting from 0 instead of 1).
Use your fingers to count from 0 - 5 and you will see that there are actually 6 numbers instead of 5 which is causing your OutOfBoundsException as you don't have a 6th element.
Therefore to access your rows and columns, the range should be between:
0 - 19 (for the columns) and 0 - 4 (for the rows)
Or
1 - 20 (for the columns) and 1 - 5 (for the rows) and then subtract 1 from your scanners input since remember arrays use 0 based index.
update for the file reading:
public static String[][] load() {
try{
FileReader fr = new FileReader("c:/temp/Address.txt");
BufferedReader bf = new BufferedReader(fr);
String presentLine = "";
for(int i = 0; i < 20; i++) {
for(int j = 0; i < 5; j++) {
if ((presentLine = bf.readLine()) != null) {
array[i][j] = presentLine;
}
}
}
} catch(Exception e) {
System.out.println(e);
}
selectMenu();
return array;
}
Although this could be made way better but it's okay.
You could store 20 and 5 as static variables called rows and columns respectively to avoid using hard coded numbers.

Reading numbers from a .txt file into a 2d array and print it on console

So basically i am trying to read a .txt file that contains these following in it:
3 5
2 3 4 5 10
4 5 2 3 7
-3 -1 0 1 5
and store them into 2D array and print it on console, what i got from the console is fine but only missing the first row 3 5, which i do not know what is wrong with my code made it ignored the first line.
what i got as output now:
2 3 4 5 10
4 5 2 3 7
-3 -1 0 1 5
import java.io.*;
import java.util.*;
public class Driver0 {
public static int[][] array;
public static int dimension1, dimension2;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to Project 0.");
System.out.println("What is the name of the data file? ");
String file = input.nextLine();
readFile(file);
}
public static void readFile(String file) {
try {
Scanner sc = new Scanner(new File(file));
dimension1 = sc.nextInt();
dimension2 = sc.nextInt();
array = new int[dimension1][dimension2];
while (sc.hasNext()) {
for (int row = 0; row < dimension1; row++) {
for (int column = 0; column < dimension2; column++) {
array[row][column] = sc.nextInt();
System.out.printf("%2d ", array[row][column]);
}
System.out.println();
}
}
sc.close();
}
catch (Exception e) {
System.out
.println("Error: file not found or insufficient requirements.");
}
}
}
You're reading those numbers in this part of your code:
dimension1 = sc.nextInt();
dimension2 = sc.nextInt();
So dimension1 gets the value of 3 and dimension2gets the value of 5, but you're not saving them into the array.
Try this code....
import java.io.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
public class Proj4 {
public static int rows, cols;
public static int[][] cells;
/**
* main reads the file and starts
* the graphical display
*/
public static void main(String[] args) throws IOException {
Scanner s = new Scanner(System.in);
String file = JOptionPane.showInputDialog(null, "Enter the input file name: ");
Scanner inFile = new Scanner(new File(file));
rows = Integer.parseInt(inFile.nextLine());
cols = Integer.parseInt(inFile.nextLine());
cells = new int[rows][cols];
//this is were I need help
for(int i=0; i < rows; i++)
{
String line = inFile.nextLine();
line = line.substring(0);
}
inFile.close();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
System.out.print(cells[i][j]);
}
System.out.print();
}
You can use Stream API to do it easily
public static Integer[][] readFile(String path) throws IOException {
return Files.lines(Paths.get(path)) // 1
.filter(line -> !line.trim().isEmpty()) // 2
.map(line -> Arrays.stream(line.split("[\\s]+")) // 3
.map(Integer::parseInt) // 4
.toArray(Integer[]::new)) // 5
.toArray(Integer[][]::new); // 6
}
Read the file as Stream of Lines
Ignore empty lines
Split each line by spaces
Parse splitted String values to get Integer values
Create an array of Integer values
Collect it in 2D-Array
The first two values are being saved into dimension1 and dimension2 variables, so when sc.nextInt gets called later, it's already read the first two numbers and moves on to the next line. So those first ints don't make it into the array.
A few things to consider:
You're wanting to use the entire file, so I would read the whole thing in at once with Files.readAllLines(). This function returns a List<String> which will have all the lines to your file. If there are any blank lines, remove them and now you have the number of rows to declare for your 2d array.
Each line is space delimited, so a simple String.split() on each line in your List<String> will give you the number of columns each row should have.
Splitting each line and converting them to integers can be done with a nested for loops which is normal for processing 2d arrays.
For Example:
public static void main(String[] args) throws Exception {
// Read the entire file in
List<String> myFileLines = Files.readAllLines(Paths.get("MyFile.txt"));
// Remove any blank lines
for (int i = myFileLines.size() - 1; i >= 0; i--) {
if (myFileLines.get(i).isEmpty()) {
myFileLines.remove(i);
}
}
// Declare you 2d array with the amount of lines that were read from the file
int[][] intArray = new int[myFileLines.size()][];
// Iterate through each row to determine the number of columns
for (int i = 0; i < myFileLines.size(); i++) {
// Split the line by spaces
String[] splitLine = myFileLines.get(i).split("\\s");
// Declare the number of columns in the row from the split
intArray[i] = new int[splitLine.length];
for (int j = 0; j < splitLine.length; j++) {
// Convert each String element to an integer
intArray[i][j] = Integer.parseInt(splitLine[j]);
}
}
// Print the integer array
for (int[] row : intArray) {
for (int col : row) {
System.out.printf("%5d ", col);
}
System.out.println();
}
}
Results:
3 5
2 3 4 5 10
4 5 2 3 7
-3 -1 0 1 5

Saturday Night Java Fun with 2D arrays, and reading a text based tab delimited file to populate such an array

Hey guys and gals hope everyones Saturday night is going as swimmingly (preferably more) than mine own.
I'm a java noob so bear with me.
We are told to export the an excel sheet from Open Office into a .txt (Tab Delimited)
It ends up looking like this
1 2 3
4 5 6
7 8 9
10 11 12
Where all values are separated by a tab.. (something I haven't encountered yet and are Integer values)
I can see one option, as i type this as I could capture each line, then string split the line by?? whitespace or /t ... and then assign the values to the respective positions in the [30][10] array...
(which ends up being a .csv and load it into java.
So Job 1 is to populate a 2D array with the files from the tab delimited file.
import java.util.Scanner;
import java.io.File;
import java.util.Arrays;
public class Nitrogen
{
private int elevations[][] = null;
private String filename = "location.txt";
public Nitrogen()
{
int [][]elevations = new int[30][10];
}
public void run()
{
try{
File file = new File(filename);
Scanner input = new Scanner(file);
int rows = 30;
int columns = 10;
int[][] elevations = new int[30][10];
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < columns; ++j)
{
if(input.hasNextInt())
{
elevations[i][j] = input.nextInt();
}
}
for (int h=0; h < rows; h++) {
for (int g=0; g < columns; g++)
System.out.print(elevations[h][g] +" ");
}
System.out.println("");
}
}
catch (java.io.FileNotFoundException e) {
System.out.println("Error opening "+filename+", ending program");
System.exit(1);}
}
public static void main(String[] args)
{
Nitrogen n = new Nitrogen();
n.run();
}
}
So, this prints out 30 lines of line 1, then a line of 0's on top of 29 lines of line 2, then 2 lines of 0's on top of 28 lines of line 3, You get the point....all moving left to right.
Not quite sure....tis getting late and i might give up for the evening.
Alright!! Here is the solution... persistence pays of thanks for the help everyone
public void populate()
{
try{
File file = new File(filename);
Scanner input = new Scanner(file);
int rows = 30;
int columns = 10;
int[][] elevations = new int[30][10];
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j)
{
if(input.hasNextInt())
{
elevations[i][j] = input.nextInt();
}
}
}
for (int h=0; h < rows; h++){ //This was just to show I had it
for (int g=0; g < columns; g++) { //in there correctly
System.out.print(elevations[h][g] +" ");
}
System.out.println(""); }
}
catch (java.io.FileNotFoundException e) {
System.out.println("Error opening "+filename+", ending program");
System.exit(1);}
}
If you are trying to print out the array, I would suggest the following amendment to your code:
for (int h=0; h < rows; h++) {
for (int g=0; g < columns; g++)
System.out.print(elevations[h][g] + " ");
}
System.out.println("");
}
The above will produce an output such as:
Row1, Row1, Row1
Row2, Row2, Row2
Because it prints out the columns, with a space in between each element, then a new line between the rows.
I know this is a simple assignment for a class, but if you can use Collections for IO, please do so. It makes the code much more generally usable.
If you want to read values from a tab delimited file (in OpenOffice, this is called a {Tab} delimited CSV file in the Save dialog window), the easiest you can do, is split each line according to a tab, like this:
public static ArrayList<ArrayList<Integer>> readFile(String filename) throws IOException {
File file = new File(filename);
BufferedReader br = new BufferedReader(new FileReader(file));
ArrayList<ArrayList<Integer>> list = new ArrayList<>(); // list of lines
String buffer;
while ((buffer = br.readLine()) != null) {
String[] splitted = buffer.split("\t"); // split the lines by tabs
ArrayList<Integer> line = new ArrayList<>();
for (String str : splitted) {
line.add(Integer.parseInt(str)); // cast and add all the integers to a list
}
list.add(line); // add the line to the list of lines
}
return list;
}
We are able to create a list of lines, with each line containing the Integer values from the text file. Now, we need to create a 2D list out of it, so concatenate all the values from every line to the line before.
public static ArrayList<Integer> concatenateAll(ArrayList<ArrayList<Integer>> lines) {
ArrayList<Integer> result = new ArrayList<>(); // create an empty 2D list for all the values
for(ArrayList<Integer> line : lines) {
result.addAll(line); // add all the values from every line to the 2D list
}
return result;
}
We can create a 2D list of all the values in the file. To use these two methods, we need to invoke them like this:
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> lineList = null;
try {
lineList = readFile("table.csv");
} catch (IOException ioe) {
ioe.printStackTrace();
}
ArrayList<Integer> allLines = concatenateAll(lineList);
System.out.println(allLines);
}
If we absolutely need an array, we can add this at the end:
Integer[] linesArray = new Integer[allLines.size()];
allLines.toArray(linesArray);
System.out.println(Arrays.toString(linesArray));
For non-class assignments, here's a one liner:
private string[][] Deserialize(string data)
{
return ( from string line
in data.Split('\r\n')
select line.Split(' ')
).ToArray();
}

Java - Read lines of file into different variables

I've worked with Java for a few years but during that time I've almost never had to do anything with text files. I need to know how to read lines of a text file into different variables as two-digit integers, along with several lines of said text file into a 2D integer array. Every text file is to be written like this:
5 5
1 2
4 3
2 4 2 1 4
0 1 2 3 5
2 0 4 4 1
2 5 5 3 2
4 3 3 2 1
The first three lines should all be separate integers, but the first line is indicative of the 2D array's dimensions. The last segment needs to go into that integer array. This is what I've got so far in terms of code.
import java.util.*;
import java.io.*;
public class Asst1Main {
public static void main(String[]args){
try {
x = new Scanner(new File("small.txt"));
} catch (FileNotFoundException e) {
System.out.println("File not found.");
}
while(x.hasNext()){
}
}
}
I'm completely at a loss of how to do this.
Here is some psuedoish code
Scanner input = new Scanner(new File("blammo.txt"));
List<String> data = new ArrayList<String>();
String line1;
String line2;
String line3;
line1 = readALine(input);
line2 = readALine(input);
line3 = readALine(input);
... process the lines as you see fit. perhaps String.split(line1);
while (input.hasNextLine())
{
String current = input.nextLine();
data.add(current);
}
private String readALine(final Scanner input)
{
String returnValue;
if (input.hasNextLine())
{
returnValue = input.nextLine();
}
else
{
returnValue = null; // maybe throw an exception instead.
}
return returnValue;
}
Once you have the data (or perhaps while reading it), you can split it and process it as you see fit.
Start with an ArrayList of integer arrays instead. It'll be easier to do this:
ArrayList<Integer[]> list = new ArrayList<Integer>();
String line = scanner.nextLine();
String[] parts = line.split("[\\s]");
Integer[] pArray = new Integer[parts.length];
for (Integer x = 0; x < parts.length; x++) {
pArray[x] = Integer.parseInt(parts[x]);
}
list.add(pArray);
Do the bulk of that inside of a loop obviously.
Here is a full version.
import java.util.*;
import java.io.*;
public class Asst1Main {
public static void main(String[] args) {
Scanner in;
try {
in = new Scanner(new File("small.txt"));
} catch (FileNotFoundException e) {
System.out.println("File not found.");
return;
}
int rows = in.nextInt();
int cols = in.nextInt();
int startRow = in.nextInt();
int startCol = in.nextInt();
int endRow = in.nextInt();
int endCol = in.nextInt();
int[][] map = new int[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
map[row][col] = in.nextInt();
}
}
}
}

Categories