I'm writing a Java program to try to parse a text file and store the contents of it in a matrix. The following is my Java code:
import java.io.*;
import java.util.*;
public class Viterbi
{
String[][] gmatrix = new String[50][4];
float[] pmatrix = new float[50];
public Viterbi(String filename)
{
BufferedReader br = null;
try
{
String currentline;
StringTokenizer st;
br = new BufferedReader(new FileReader(filename));
while((currentline = br.readLine()) != null)
{
st = new StringTokenizer(currentline, ";");
while(st.hasMoreTokens())
{
for(int i=0; i<50; i++)
{
for(int j=0; j<4; j++)
{
gmatrix[i][j] = st.nextToken();
System.out.println("i --> " + i + " j--> " + j + ": " + gmatrix[i][j]+"\t");
}
}
}
}
for(int i=0; i<50; i++)
{
for(int j=0; j<3; j++)
System.out.print(gmatrix[i][j]+"\t");
System.out.println("");
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if(br != null)
br.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
Viterbi v = new Viterbi("rules.txt");
}
}
And here's the contents of the text file:
S;a;S;0.6
S;b;X;0.4
X;c;$;0.1
X;X;$;0.9
I want the output to be displayed in the gmatrix as:
S a s
S b X
X c $
X X $
But for some reason I get the following output and exception:
i --> 0 j--> 0: S
i --> 0 j--> 1: a
i --> 0 j--> 2: S
i --> 0 j--> 3: 0.6
java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at Viterbi.<init>(Viterbi.java:27)
at Viterbi.main(Viterbi.java:62)
How can I print the correct output as desired?
In your code, you are only calling hasNextToken() once at the start of the while condition. You need to call hasNextToken() as many times as nextToken(), to make sure that nextToken() will work. The reason you don't have any more tokens on the line is that there are only 4 tokens per line (apparently) but you have two for loops that will try to call nextToken() a total of 50*4=200 times.
Alternatively to how you are doing this: you could just split the currentLine on ";" with the split() method and then loop through the returned String[] elements.
In your first while loop, you are actually trying to populate the whole gmatrix by parsing a single line of the input file. This is not what you expect. Since there are only 4 tokens in the first line, you get the exception when you are trying to call st.nextToken() to get the next (non-existing) token when the program is trying to get gmatrix[1][0].
To correct your code, you should check and read a new input line in your first for(int i = ...) loop, and remove the 2 out-most while loops.
Example:
for(int i = 0; ...){
// check if there is another line in input;
// tokenize a line of input;
for(int j = 0; ...){
// get a token and populate one element in gmatrix;
}
}
Instead of using the two while loops.
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 a text file that contains three lines of code.
That is,
Hello.
How may I help you?
What can I do for you today?
I tried printing the first line and it worked.Now I want to print the rest of the lines in the console but it's only displaying first line 4 times like this.
Hello.
Hello.
Hello.
Hello.
Below is the code that I am trying to run and the file is in root folder.
public class Test
{
public static void main(String[] args)
{
int counter = 0;
/*open the file */
BufferedReader reader = null;
String greeting = null;
int rand;
File file = new File("Greetings.txt");
try
{
reader = new BufferedReader(new FileReader(file));
/*read the file*/
String greetingPicker = null;
/*single greeting*/
/*greeting = greetingPicker;*/
List<String> listOfGreetings = new ArrayList<String>();
while ((greetingPicker = reader.readLine()) != null)
{
listOfGreetings.add(greetingPicker);
}
reader.close();
rand = (int) Math.random() * (listOfGreetings.size()) + 1;
greeting = listOfGreetings.get(rand - 1);
for (int i = 0; i < listOfGreetings.size(); i++)
{
System.out.println(listOfGreetings.get(counter));
}
} catch (Exception e)
{
System.out.println("File cannot be found!!");
}
}
}
You are getting the value for the wrong index: You mistakenly used counter instead of i in your loop. Change this
for(int i=0; i < listOfGreetings.size(); i++){
System.out.println(listOfGreetings.get(counter));
}
to this:
for(int i=0; i < listOfGreetings.size(); i++){
System.out.println(listOfGreetings.get(i));
}
By the way, you are using Math.random() and it is instantly converted to a int, because you forgot to add correct parentheses, so change this
rand = (int) Math.random() * (listOfGreetings.size()) + 1;
to this:
rand = (int) (Math.random() * (listOfGreetings.size()) + 1);
You dont need your counter, use i ! ;)
for(int i=0; i < listOfGreetings.size();i++){
System.out.println(listOfGreetings.get(i));
}
Just change
System.out.println(listOfGreetings.get(counter));
by
System.out.println(listOfGreetings.get(i));
You forgot to change the counter.
You don't need to use counter, and put close in the end like this:
for(int i=0; i < listOfGreetings.size();i++){
System.out.println(listOfGreetings.get(i));
}
reader.close();
The "counter" variable here is not being incremented:
for(int i=0; i < listOfGreetings.size();i++){
System.out.println(listOfGreetings.get(counter));
}
You should change it to "i" instead:
for(int i=0; i < listOfGreetings.size();i++){
System.out.println(listOfGreetings.get(i));
}
Try using the chunk below. It's simpler and works perfectly.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class FileReader{
public static void main(String[] args){
//define file path
String stringFileToRead = "Greetings.txt";
//the file
File stringFile = new File(stringFileToRead);
//Scanner object to take input from the file
Scanner fileToRead = null;
try{
//Read the file
fileToRead = new Scanner(stringFile);
}
//catch exception
catch (Exception e){
System.out.println("Unable to open file.");
System.exit(0);
}
//print the content of the file
System.out.println("The file contains the following contents:\n");
int lineNum = 1;
while(fileToRead.hasNextLine()){
String line = fileToRead.nextLine();
System.out.println("Line "+lineNum+": "+line);
lineNum++;
}
}
}
I can't understand why my program not functioning. It compiles but nothing is printed. I have a 5 character word in file. I need to read line from that file and then split it into char array, which I then want print out.Thanks!
import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedReader;
public class test {
public static void main(String[] args)
{
BufferedReader line = null;
char[] array = new char[7];
try{
line = new BufferedReader(new FileReader(args[0]));
String currentLine;
while((currentLine = line.readLine()) != null)
{
array = currentLine.toCharArray();
}
for(int i = 0; i < array.length; i++)
{
System.out.print(array[i]);
}
}//try
catch(IOException exception)
{
System.err.println(exception);
}//catch
finally
{
try
{
if(line != null)
line.close();
}//try
catch(IOException exception)
{
System.err.println("error!" + exception);
}//catch
}//finally
} // main
} // test
Your while loop skips every line except the last one so it could be possible that your last line is empty. To display every line you could have:
while ((currentLine = line.readLine()) != null) {
array = currentLine.toCharArray();
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
System.out.println();
}
Or if you just have the 1 line, You could simply use:
String currentLine = line.readLine();
...
Your program prints only last line
You have to Print in loop.
while (....!=null)
{
array = currentLine.toCharArray();
for(int i = 0; i < array.length; i++)
{
System.out.print(array[i]);
}
}
If above was not a problem than check your file permission.
Check your system may be program is not able to read from file due to permission on file.
Say I have a file of the following format:
3
4
1,2,3,4
5,6,7,8
9,10,11,12
The first two lines of the file represent the number of rows and columns of a 2D array. Thereafter, each line represents the values of each row of the 2D array. I am trying to read this file and create a 2D integer array in java. I tried the following code:
public class PrintSpiral {
private static BufferedReader in = null;
private static int rows = 0;
private static int columns = 0;
private static int [][] matrix = null;
public static void main(String []args) throws Exception {
try {
String filepath = args[0];
int lineNum = 0;
int row=0;
in = new BufferedReader(new FileReader(filepath));
String line = in.readLine();
while(line!=null) {
lineNum++;
if(lineNum==1) {
rows = Integer.parseInt(line);
System.out.println("The number of rows of the matrix are: " + rows);
} else if(lineNum==2) {
columns = Integer.parseInt(line);
System.out.println("The number of columns of the matrix are: " + columns);
matrix = new int[rows][columns];
} else {
String [] tokens = line.split(",");
for (int j=0; j<tokens.length; j++) {
System.out.println("I am filling the row: " + row);
matrix[row][j] = Integer.parseInt(tokens[j]);
}
row++;
}
}
} catch (Exception ex) {
System.out.println("The code throws an exception");
System.out.println(ex.getMessage());
} finally {
if (in!=null) in.close();
}
System.out.println("I am printing the matrix: ");
for (int i=0; i < rows; i++) {
for(int j=0; j < columns; j++)
System.out.print(matrix[i][j]);
System.out.println("");
}
}
}
The output that I see is:
The number of rows of the matrix are: 3
The number of columns of the matrix are: 3
I am filling the row: 0
I am filling the row: 1
I am filling the row: 2
I am filling the row: 3
The code throws an exception
3
I am printing the matrix:
300
300
300
3 0 0 0 0 0 3 3 0
Clearly, the java code is not reading the file correctly. Also, my code throws an exception. I am not sure what causes this exception. I can't seem to figure out what's wrong with my code. Thanks!
change
in = new BufferedReader(new FileReader(filepath));
String line = in.readLine();
while(line!=null) { .....
to
in = new BufferedReader(new FileReader(filepath));
String line = null;
while((line = in.readLine()) !=null) { .....
to read a new line at the start of each loop
You (very obviously) don't have a readLine() inside your loop, so it only ever reads the first line of the file.
Why bother having to specify the rows/columns? Why not just figure it out from the data itself?
at the end of the while loop, add in.readline();
you are just keeping the same line forever and looping on it.
I am new to Java. I have one text file with below content.
`trace` -
structure(
list(
"a" = structure(c(0.748701,0.243802,0.227221,0.752231,0.261118,0.263976,1.19737,0.22047,0.222584,0.835411)),
"b" = structure(c(1.4019,0.486955,-0.127144,0.642778,0.379787,-0.105249,1.0063,0.613083,-0.165703,0.695775))
)
)
Now what I want is, I need to get "a" and "b" as two different array list.
You need to read the file line by line. It is done with a BufferedReader like this :
try {
FileInputStream fstream = new FileInputStream("input.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
int lineNumber = 0;
double [] a = null;
double [] b = null;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
lineNumber++;
if( lineNumber == 4 ){
a = getDoubleArray(strLine);
}else if( lineNumber == 5 ){
b = getDoubleArray(strLine);
}
}
// Close the input stream
in.close();
//print the contents of a
for(int i = 0; i < a.length; i++){
System.out.println("a["+i+"] = "+a[i]);
}
} catch (Exception e) {// Catch exception if any
System.err.println("Error: " + e.getMessage());
}
Assuming your "a" and"b" are on the fourth and fifth line of the file, you need to call a method when these lines are met that will return an array of double :
private static double[] getDoubleArray(String strLine) {
double[] a;
String[] split = strLine.split("[,)]"); //split the line at the ',' and ')' characters
a = new double[split.length-1];
for(int i = 0; i < a.length; i++){
a[i] = Double.parseDouble(split[i+1]); //get the double value of the String
}
return a;
}
Hope this helps. I would still highly recommend reading the Java I/O and String tutorials.
You can play with split. First find the line in the text that matches "a" (or "b"). Then do something like this:
Array[] first= line.split("("); //first[2] will contain the values
Then:
Array[] arrayList = first[2].split(",");
You will have the numbers in arrayList[]. Be carefull with the final brackets )), because they have a "," right after. But that is code depuration and it is your mission. I gave you the idea.