When I convert my Java project into a Jar file, an ArrayIndexOutOfBounds exception of -2 occurs in line 3 of this section of code:
for (int i = 0; i < copy.get(copy.size() - 2).size(); i++) {
if (!copy.get(copy.size() - 2).get(i).toString().equals(" ")) {
startLocations[index] = Integer.parseInt(copy.get(copy.size() - 2).get(i).toString());
index++;
}
}
I find this very strange because the program runs perfectly fine in Eclipse, and the size of copy, a 2D ArrayList tempoarily holding the grid of a maze is 9. The code fails when I convert it to a Jar and I run it from cmd. Here is the full relevant code below. All the files are in their correct locations.
String fileName = "maze.txt";
String line = null;
ArrayList < ArrayList < Square >> grid = new ArrayList < ArrayList < Square >> ();
try {
// Setup FileReader, BufferedReader, and LineReader
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
int row = 0;
// Get all the lines inside the maze file
while ((line = bufferedReader.readLine()) != null) {
ArrayList < Square > lineList = new ArrayList < Square > ();
for (int i = 0; i < line.length(); i++) {
String letter = Character.toString(line.charAt(i));
if (letter.equals("L")) {
lineList.add(new LockedSquare(row, i, letter));
} else {
lineList.add(new Square(row, i, letter));
}
row++;
}
grid.add(lineList);
}
// Cut down grid to only the maze
ArrayList < ArrayList < Square >> copy = grid;
int length = grid.size();
grid = new ArrayList < ArrayList < Square >> ();
for (int i = 0; i < length - 2; i++) {
grid.add(copy.get(i));
}
// Start position
int[] startLocations = new int[2];
int index = 0;
for (int i = 0; i < copy.get(copy.size() - 2).size(); i++) {
if (!copy.get(copy.size() - 2).get(i).toString().equals(" ")) {
startLocations[index] = Integer.parseInt(copy.get(copy.size() - 2).get(i).toString());
index++;
}
}
int playerX = startLocations[0];
int playerY = startLocations[1];
}
// Exceptions
catch (FileNotFoundException e) {
System.out.println("Error: maze.txt not found");
} catch (IOException ex) {
System.out.println("Error reading maze.txt");
}
This is happening because your jar file is unable to find maze.txt .
change String fileName = "maze.txt";
to
String fileName = <absolute-path-for-maze.txt> ; and it should be through in jar
Woops. I was so stupid. My maze.txt file in the same folder as my JAR has no content in it.
Related
I am running a 4*4 maze all possible solution finding programme.
I have set up a method that takes a random combination Value of"R, G, B, Y" as aStrin and checks if the given String is a valid solution or not. for instance, the given String is "RGGGBYYBBGYBGRR".
new Thread(() -> {
//List<String> temp1 = new ArrayList<>();
String[] letters = {"R","G","B","Y"};
int done = 0;
Cell start = MazeBuilder.mazeFor(REPO_NAME);
while (done != 1) {
String str = "";
int r = ThreadLocalRandom.current().nextInt(10, 48);
//done = check(temp1, letters, done, start, str, r);
for (int j = 0; j < r; j++) {
Random rnd = new Random();
int index = rnd.nextInt(letters.length);
str += letters[index];
}
if (Helper.isValidSolution(start, str)) {
done = 1;
try {
FileWriter FW = new FileWriter("ansGrid.txt");
FW.write(str);
FW.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
so my question is... if the programme crashes or it runs out of memory, how can I store the values of the temp1 variable in a file?
I have a .txt file that contains text that I would like to save part of it in a String, part of it in a String array, and then the last part in a 2D int array, and am faced with two issues:
How to read and save both of the arrays when their size is not known ahead of time?
2D array is not reading/saving properly
Here is the text file for reference:
This is the sentence to be read.
This
is
a
String
array.
90 47 110 95 95
101 87
54 0 38 12
Here is part of my method that is supposed to read and save the three data types:
BufferedReader br = new BufferedReader(new FileReader(fileName));
sentence = br.readLine();
stringArr = new String[5]; //how to initialize without set number of elements?
for(int i = 0; i<stringArr.length; i++){
stringArr[i] = br.readLine();
}
int2DArr = new int[3][5]; //how to initialize with any amount of rows and columns?
for(int i = 0; i<int2DArr.length; i++){
for(int j = 0; j<int2DArr[i].length; j++){
int2DArr[i][j] = br.read();
//how to read the space after each int ?
}
}
How would I "grab" the size of the arrays by reading the text file, so that when I initialize both arrays, I have the proper sizes? Any help would be greatly appreciated!
Instead of trying to achieve everything in a single pass we can pass through the file twice and obtain a neater code.
It will consume double time of course but it is going to help you understand how you could break bigger problems into smaller ones and deal with them one by one.
Here are the steps:
Determine size of stringArr and intArr in first pass
Fill value in respective array in second pass
If you are wondering how no of columns for int2DArr is determine. Simply we don't do it our self. We use the concept of Jagged Arrays
Read more here How do I create a jagged 2d array in Java?
import java.util.*;
import java.io.*;
class ReadFileIntoArr {
public static void main(String args[]) throws IOException {
String fileName = "test.txt";
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = br.readLine();
int strSize = 0;
int intSize = 0;
boolean isDigit = false;
while (line != null && line.trim().length() != 0) {
if (!isDigit && Character.isDigit(line.charAt(0)))
isDigit = true;
if (isDigit)
intSize++;
else
strSize++;
line = br.readLine();
}
br = new BufferedReader(new FileReader(fileName));
String[] stringArr = new String[strSize];
for (int i = 0; i < stringArr.length; i++)
stringArr[i] = br.readLine();
int[][] int2DArr = new int[intSize][];
for (int i = 0; i < int2DArr.length; i++)
int2DArr[i] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
System.out.println(Arrays.toString(stringArr));
System.out.println(Arrays.deepToString(int2DArr));
}
}
Note: In single pass this could be accomplished with the help of ArrayList and later transfer everything into respective array.
Update: After understanding the constraints for your problem here is another version
import java.util.*;
import java.io.*;
class ReadFileIntoArr {
public static void main(String args[]) throws IOException {
String fileName = "test.txt";
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = br.readLine();
int strSize = 0;
int intSize = 0;
boolean isDigit = false;
while (line != null && line.trim().length() != 0) {
if (!isDigit && isDigit(line.charAt(0)))
isDigit = true;
if (isDigit)
intSize++;
else
strSize++;
line = br.readLine();
}
br = new BufferedReader(new FileReader(fileName));
String[] stringArr = new String[strSize];
for (int i = 0; i < stringArr.length; i++)
stringArr[i] = br.readLine();
int[][] int2DArr = new int[intSize][];
for (int i = 0; i < int2DArr.length; i++)
int2DArr[i] = convertStringArrToIntArr(br.readLine().split(" "));
System.out.println(Arrays.toString(stringArr));
System.out.println(Arrays.deepToString(int2DArr));
}
public static boolean isDigit(char c) {
return c >= '0' && c <= '9';
}
public static int[] convertStringArrToIntArr(String[] strArr) {
int[] intArr = new int[strArr.length];
for (int i = 0; i < strArr.length; i++)
intArr[i] = Integer.parseInt(strArr[i]);
return intArr;
}
}
Path path = Paths.get(fileName);
List<String> lines = Files.readAllLines(path, Charset.defaultCharset());
String title = lines.get(0);
List<String> words = new ArrayList<>();
for (int i = 1; i < lines.size(); ++i) {
String word = lines.get(i);
if (!word.isEmpty() && Character.isDigit(word.codePointAt(0)) {
break;
}
words.add(word);
}
String[] wordArray = words.toArray(new String[]);
int i0 = 1 + words.size();
int n = lines.size() - i0;
int[][] numbers = new int[n][];
for (int i = i0; i < lines.size(); ++i) {
String[] values = lines.get(i).trim().split("\\s+");
int m = values.length;
int[] row = new int[m];
for (int j = 0; j < m; ++m) {
row[j] = Integer.parse(values[j]);
}
numbers[i - i0] = row;
}
Path is a generalisation of File, also URLs.
Files is a treasure trove of file functions.
One could do without dynamically sized List; one would need to test first,
but normally one would use a List anyhow.
String.split splits on one or more whitespace.
Hi for my HW I am suppose to read a text file of '.' and 'x' representing cells in Conway's Game of Life. I'm having trouble with reading the given text input and adding it into my double integer arrays. Specifically the rowcounter and columncounter part I'm sure there is a better way to do it but when I tried for loops it only read one row. I included previous parts of the code just in case. Thanks.
// Initiate file
File inputfile = new File(inputfilename);
try {
input = new Scanner(inputfile);
} catch (Exception ie) {
}
// Get array size
int[] arraysize = new int[2];
while (input.hasNextInt()) {
for (int i = 0; i < 2; i++) {
int token = input.nextInt();
arraysize[i] = token;
}
}
//System.out.println(Arrays.toString(arraysize));
// Create Array
int[][] newarray = new int[arraysize[0]][arraysize[1]];
//System.out.println(Arrays.deepToString(newarray));
// Read initial
int rowcounter = 0;
int columncounter = 0;
while (input.hasNextLine()) {
Scanner inputtoken = new Scanner(input.nextLine());
while (inputtoken.hasNext()) {
String token = inputtoken.next();
//System.out.print(token);
char xchar = token.charAt(0);
if (xchar == 'x') {
newarray[rowcounter][columncounter] = 1;
} else {
newarray[rowcounter][columncounter] = 0;
//System.out.print(rowcounter);
}
columncounter = columncounter + 1;
//System.out.print(columncounter);
}
columncounter = 0;
System.out.println();
rowcounter = rowcounter + 1;
//System.out.print(rowcounter);
}
System.out.println(Arrays.deepToString(newarray));
I have 6 columns in one table and one of the column contains Chinese character and I have 200 records in that table.
I have written the code to save it one text file. The problem is while fetching all records, I am able to see the chinese text in the file. But while fetching only one record I am seeing the Chinese text is garbled.
I am using the below code.
public static void main(String args[]){
String outputFile = fileNameEncode("C:\\a\a.txt");
FileOutputStream os = new FileOutputStream(outputFile);
writeToFile(os);
}
private static String fileNameEncode(String name) {
String file;
try {
byte[] utf_byte = name.getBytes("UTF-8");
StringBuilder sb = new StringBuilder(1024);
for (byte b : utf_byte) {
int integer = b & 0xFF; // drop the minus sign
sb.append((char) integer);
}
file = sb.toString();
} catch (Exception e) {
file = name;
}
return file;
}
public void writeToFile(FileOutputStream os) {
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(ostream, "GBK")));
for (int rowNum = 0; rowNum < arrayList.size(); rowNum++) {//arrayList contains data from db
ArrayList list = arrayList.get(rowNum);
for(int k = 0; k < list.size(); k++{
String[] data = new String[6];
for (int colNum = 0; colNum < 6; colNum++) {
data[colNum] = list.get(i).toString();
}
String outLine = composeLine(data, ctlInfo);
// write the line
pw.print(outLine);
pw.println();
}
}
}
private static String composeLine(String[] data, ControlInfo ctl) {
StringBuilder line = new StringBuilder();
String delim = ","
int elemCount = data.length;
for (int i = 0; i < elemCount; i++) {
if (i > 0)
line.append(delim);
if (data[i] != null && (data[i].contains("\n") || data[i].contains("\r") ||
data[i].contains("\r\n"))){
data[i] = data[i].replaceAll("(\\t|\\r?\\n)+", " ");
}
else {
line.append(data[i]);
}
}
return line.toString();
}
could you please let me know where I am wrong?
I found the issue, the code is good, the problem is in notepad++. If the character set in node pad ++ is Chinese(GB2312) then I am able to see the correct text. The note pad ++ is auto set GB2312 for two lines but for one line it is not doing auto set to GB2312.
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.