I' re-doing an exam for practicing and i've almost completed it. The only problem i have is with this part:
int z=0,x=0;
String line="";
RandomAccessFile read = new RandomAccessFile(s, "rw");
while((read.readLine())!=null)
z++;
read.seek(0);
while(x<z){
line=read.readLine();
StringTokenizer stk = new StringTokenizer(line, " ");
if(line.charAt(0)=='r'){
nr=z;
nc=stk.countTokens()-1;
valori = new int[nr][nc];
while(stk.hasMoreTokens()){
stk.nextToken();
for(int i=0; i<nr; i++)
for(int j=0; j<nc; j++)
valori[i][j] = Integer.parseInt(stk.nextToken());}
}
else if(line.charAt(0)=='c'){
nr=stk.countTokens()-1;
nc=z;
valori = new int[nr][nc];
while(stk.hasMoreTokens()){
stk.nextToken();
for(int i=0; i<nr; i++)
for(int j=0; j<nc-1; j++)
valori[j][i] = Integer.parseInt(stk.nextToken());}
}x++;
Basically i have to read a file where i have the description of a matrix as follows:
c 0 1 0
c 0 0 1
c 0 0 0
c 1 0 0
And the resulting matrix would be
|0|0|0|1|
|1|0|0|0|
|0|1|0|0|
After reading the file i have to build the matrix with a 2d int array, i used the same code from another exercise but when using stk.nextToken() i get java.util.NoSuchElementException at java.util.StringTokenizer.nextToken(Unknown Source)
I cannot find the error, 2d arrays are correctly initialized and filled.
Thanks in advance for any help.
The "Unknown Source" part of the exception is an effect of running your code through the jre instead of the JDK. If you run with the JDK, your runtime environment will have access to the debug info and proper line numbers will be printed instead.
a quick look suggests that this section is in error:
nr=stk.countTokens()-1;
nc=z; //z == # of rows
//first pass through = hasMoreTokens == true (a total of 4: C,0,1,0)
while(stk.hasMoreTokens()){
//first token - C
stk.nextToken();
//this will iterate 3 times
for(int i = 0; i < nr; i++)
//this, too, will iterate 4 times - a total of 12 times considering
// the outer loop
for(int j = 0; j < nc-1; j++)
// after 3 passes, this will throw the exception
valori[j][i] = Integer.parseInt(stk.nextToken());}
}x++;
This error means that there are no more tokens in the StringTokenizer remaining, and you are asking for a one more token. "Unknown source" is not relevant to your problem - this just means you have no access to the source code of the Java system library but I doubt it will be helpful.
This happens because the line you read from the file contains less space delimited tokens than you expect.
The error happens because you are tokenizing one single line, and in the two for loops you are reading columns and rows.
Instead of using the StringTokenizer with while loops I would recommend to use the .split command:
int j=0;
// read all rows
while((read.readLine())!=null) {
String line=read.readLine();
String[] columns=line.split(" ");
// read columns of each row
int i=0;
for (String column: columns) {
if (!column.equals("c")) {
valori[j][i] = Integer.parseInt(column);
}
i++;
}
j++;
}
PS: Pseudo code above, untested.
Related
I was working through a project and I have to use charAt to continuously add elements of an array from a text file to a new array that i would have specified. The size of the array differs depending on the text file being used so it is best to assume that the contents of the file are unknown, however i will provide an example.
I keep on getting a "StringIndexOutOfBoundException" when i run my code and i am not sure why, or how to fix it.
What the code should be doing is taking the user input to get the exact text file location, then it will be reading that line by line and adding that to a new array. The first two lines of the text file array are the array row and column size.
my code is as follows:
public static void main(String[] args) throws FileNotFoundException
{
System.out.println("Enter the location of the board file using the FULL PATH NAME.");
Scanner input = new Scanner(System.in);
String n = input.nextLine();
input.close();
File a = new File(n);
Scanner sc = new Scanner(a);
int row = sc.nextInt();
int col = sc.nextInt();
char[][] board = new char[row][col];
for (int numRow = 0; numRow < row+1; numRow ++)
{
String string = sc.next();
for (int numCol = 0; numCol < col+1; numCol++)
{
board[row][col] = string.charAt(numCol);
}
}
sc.close();
GridGame game = new GridGame (row, col, board);
game.playGame();
An example input text file:
10 10
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
TWWWWWWWWW
The issue you are facing is because a Java array has 0-based index i.e. the index of the first element is 0 and that of the last element is array.length - 1. Therefore, your loop with the variable as the index of the array should not go beyond array.length - 1. Your terminating condition, numRow < row+1 is taking the value of numRow up to the length of the array instead of array.length - 1.
Replace
for (int numRow = 0; numRow < row+1; numRow ++)
{
String string = sc.next();
for (int numCol = 0; numCol < col+1; numCol++)
{
board[row][col] = string.charAt(numCol);
}
}
with
for (int r = 0; r < row && sc.hasNextLine(); r++) {
board[r] = sc.nextLine().toCharArray();
}
The other concept you need to understand is a 2-D array in Java an array of arrays i.e. board[0] should hold the array of characters from the first line of the file, board[1] should hold the array of characters from the second line of the file and so on. Now, if you want to access the 4th character of the 3rd line from the file, you can access it as board[2][3].
The last but not the least is regarding closing the Scanner for System.in. You should never close this Scanner because it also closes the System.in. So, you should remove the line, input.close() from your code.
Update
You can write the above mentioned single loop as a nested loop as well but it is unnecessary.
for (int r = 0; r < row && sc.hasNextLine(); r++) {
char[] lineChars = sc.nextLine().toCharArray();
for(int c = 0; c < col; c++) {
board[r][c] = lineChars [c];
}
}
You need a nested loop in order to access/process individual characters but to store/access/process each row of a 2-D array, you do not need a nested loop. As I have already mentioned, a 2-D array is an array of 1-D arrays and therefore to access each of these 1-D arrays (not individual elements inside these 1-D arrays), you need a single loop, not a nested loop.
I have an issue with string array where's the program takes the use names the put it in the screen. I did some coding and creating 2D games and android app but the fact I never used array for saving scores or something and now I'm stuck and need to learn it and code below think of it as we are putting degrees for collage students put the error that the array is making an error and I can't figure it out why the full code below:
public static void main(String[] args) {
// TODO Auto-generated method stub
Chatlength = new String[10];
for(i =0; i <= Chatlength.length ; i++){
Scanner s = new Scanner(System.in);
String ss = s.nextLine();
Chatlength[i] = ss;
}
while(true){
if(i > Chatlength.length){
int ints = 0;
while(ints <10){
System.out.println("Name "+ints+": "+Chatlength[ints]);
ints++;
}
}
}
It gives me and error with Chatlength[i] = ss;.
I'm guessing you're getting an ArrayIndexOutOfBoundsException due to your loop bounds:
for(i =0; i <= Chatlength.length ; i++){
That should be:
for (int i = 0; i < Chatlength.length; i++) {
... using a local variable declaration instead of the static variable which I assume you've declared in code that you haven't shown us.
An array of length 10 has valid indexes of 0 to 9 inclusive. It's very rare that you actually want <= for a loop index variable when you're trying to iterate over a collection. (All the standard collections in Java are 0-based, so you pretty much always want to have an exclusive upper bound.)
Additionally, I strongly suggest that you start following Java naming conventions.
The condition is culprit. You are going one plus the size of array.
i <= Chatlength.length
Change it to
i < Chatlength.length
Check your for - loop:
for(i =0; i <= Chatlength.length ; i++)
should be
for(i =0; i < Chatlength.length ; i++)
you didn't declare the array first:
Chatlength = new String[10]; //Wrong code;
change it to :
String[] Chatlength = new String[10];
then java is zero based and you should use this:
for(i =0; i < Chatlength.length ; i++)
There is no such index i=10 for the array you created, as per your condition in loop, it allows i=10 (i<= Chatlength.length) which is not a valid array location hence you got the exception
Alright, lets try this again, sorry for the poor title I don't know what to call this. I haven't done much File I/O before, I personally think Java is absolutely terrible at it but nonetheless I have to do it.
A bit of background information, this is my Conway's Game of Life project, and all of my other code works fine I just need to do the I/O now.
I'm reading in from a text file, that looks like this.
So what this does is the first two numbers are the size of that the array needs to be, the String after them is irrelevant. And after that is the array of the cell arrangement in this example it's that of the glider. Now my problem is that I don't know how to store the first line in a String, and the rest in an array. Below is what I've done, and brace yourselves for a Big O of n^∞.
public char[][] fileIO(){
ArrayList<String> list = new ArrayList<String>();
char[][] newArray;
String[] tokens;
BufferedReader reader;
String inputLine;
try{
reader = new BufferedReader(new FileReader("untitled.txt"));
while((inputLine = reader.readLine()) != null){
list.add(inputLine);
}
reader.close();
}catch (IOException e){
System.out.println(e);
}
tokens = list.get(0).trim().split("\\s+");
newArray = new char[Integer.parseInt(tokens[0])][Integer.parseInt(tokens[1])];
for(int row = 0; row < newArray.length; row++){
for(int col = 0; col < newArray[row].length; col++){
for(int line = 1; line < list.size(); line++){
for(int Char = 0; Char < list.get(line).length(); Char++){
newArray[row][col] = list.get(line).charAt(Char);
}
}
}
}
return newArray;
}
I know there's a lack of comments, so I'll try to explain what I tried to do now;
I read from the file and stored it all in an ArrayList
Got the tokens of the first like (10 20 Glider), and created an instantiated an array with the values 10 and 20
Then proceeded to loop through the array's rows and columns, then each line of the inputted array, and then looped through each character of that line to add into the array at their respected positions.
However, this doesn't seem to be working and I'm sure there is a much simpler and efficient way of doing this. So I ask again, can anyone tell me of a simpler way of doing this I/O? I don't need the code, just an explanation of how to do so.
In this:
for(int row = 0; row < newArray.length; row++){
for(int col = 0; col < newArray[row].length; col++){
for(int line = 1; line < list.size(); line++){
for(int Char = 0; Char < list.get(line).length(); Char++){
newArray[row][col] = list.get(line).charAt(Char);
}
}
}
}
You have two outer loops that are browsing through your newArray grid, and two inner loops that are browsing through the lines of the file. By doing that, you are essentially writing every char of every lines of your file into each cell of your grid, one after the other. In the end, you will have the last character of the last line of your file in all the cells of newArray. This is probably not what you want to do.
Edit: If I understand correctly, the number at the beginning of the file are the number of lines and the number of columns of the data that follow. Then you just have to use the two outer loops, and use row and col to access respectively the line in list and the character in the line.
I'm new to Java programming...
I'm trying to read data from text file and save it into 2D array. So basically, program will receive parameter (IP) and look for the file with same IP number.
And the program will read each line and store into an 2D array.
My attempt:
String ipNum = request.getParameter("ipNum");
String root = getServletContext().getRealPath("/");
String dailyPath = root + "\\" + ipNum +".txt";
int[][] myarray = new int[3][6];
BufferedReader br = new BufferedReader(new FileReader(dailyPath));
String line = " ";
String [] temp;
while ((line = br.readLine())!= null){
temp = line.split(" ");
for(int i = 0; i<myarray.length; i++) {
for (int j = 0; j<myarray.length; j++) {
myarray[i][j] = Integer.parseInt(temp[i]);
}
}
}
Data:
CPU 30 30 30 30 30 30
RAM 70 70 70 70 70 70
HAR 80 80 80 80 80 80
NET 100 100 100 100 100 100
the problem that I'm having is that when I call array, I always get 100 or 0 (assuming empty)
so for example myarray[1][2] should output 30 but i get 100
myarray [2][4] = 70 but i get 100...
I tried to play around with the code for past few hours, I can't figure it out...is my whole code wrong or something?
Thanks for help!
Yeah, you are iterating twice and therefore filling your array with the last value... try this code:
int i = 0;
while ((line = br.readLine())!= null){
temp = line.split(" ");
for (int j = 0; j<myarray[i].length; j++) {
myarray[i][j] = Integer.parseInt(temp[j]);
}
i++;
}
Hope this helps...
Besides Joshs remark you also set the termination conditions the wrong way.
for(int i = 0; i< myarray.length; i++) {
for (int j = 0; j< myarray[i].length; j++) {
myarray[i][j] = Integer.parseInt(temp[i]);
}
}
This way you can iterate through the array but you can't use this to solve your problem. Instead you need to use 1 while-loop and 1 for-loop.
It looks to me like you're reading each line of text and then parsing that line into a 2D array. This isn't entirely correct as each line can be considered a row. Maybe you could use a counter for each line you read in your while ((line = br.readLine())!= null) loop and then only read into the row of your 2D array at the counter index... like so:
int rowCounter = 0;
while ((line = br.readLine())!= null) {
for(int i = 0; i<myarray.length; i++)
myarray[rowCounter][i] = Integer.parseInt(temp[i]);
rowCounter++;
}
As a side note, if you did want to index into a multidimensional array you also have a side problem. In both of your loops you are iterating until you reach the max number of rows. For your j loop going through the columns this might cause a problem. Instead when using a 2D loop try:
for(int i = 0; i < array.Length; i++)
for(int j = 0; j < array[0].Length; j++)
//Do some stuff
Your 'while' loop and your first 'for' loop are performing a similar task--for each line you read, you are iterating over every row in your array and filling it's columns with the line you are reading. Every value is 100 because the last line you read is full of 100s.
I suggest removing the first 'for' loop, declare 'int i = 0;' before the 'while' loop, and an 'i++' at the bottom (but inside) the for loop.
#Vivek makes a good point that you need to measure 'myArray[ i ].length' for your j counter.
What I'm trying to do is I have this program which reads in a number, and that number designates how many words there are, for example:
3
red
blue
green
And then prints out that same text but in reverse order so it would be
green
blue
red
followed by a blank line indicating to the server that you are done with that specific problem. But I seem to have a bug in my code somewhere.
I tried to store the words in an array List. I used a for loop to store them in the list and then to print them out in reverse order I just used another for loop going the opposite way, starting from the end of the list going to the beginning.
When I run the program from the command prompt it just goes to the next command prompt line as if I had as it to compile the program, there are no errors but when I
did a test, using a test program I created, it seems that the program reads the number but then goes and prints out a blank array.
It would seem as though the words from the server don't get stored in the array and I'm not sure what I'm doing wrong. I'm not the greatest programmer so any help would greatly be appreciated.
The Code:
import java.io.*;
import java.util.*;
public class Solution
{
public static void run(BufferedReader in, PrintWriter out)
throws IOException
{
int x = Integer.parseInt(in.readLine());
while(x != 0)
{
ArrayList num = new ArrayList();
for(int i = 0; i < num.size(); i++)
{
//String f = in.readLine();
num.add(in.readLine());
}
//System.out.println(num);
for(int i = num.size()-1; i > 0; i--)
{
out.println(num.get(i));
//x = Integer.parseInt(in.readLine());
System.out.println();
}
break;
}
out.flush();
}
}
ArrayList num = new ArrayList();
for(int i = 0; i < num.size(); i++)
means you go from 0 to... 0!
for(int i = 0; i < x; i++)
would be better.
The while loop never stops
EDIT: Oops no, this is not true, but what is the point of having a while loop that runs once? You put a break at the end of it, so maybe you could refactor that to an if? Maybe a guard?
The size of num here is 0. You should use 'x' instead of num.size()
for(int i = 0; i < num.size(); i++)
{
//String f = in.readLine();
num.add(in.readLine());
}
This might not be the exact what you have done.. a bit different.. :-)
int x = Integer.parseInt(in.readLine());
String[] arr = new String[x]; // Edited :: Slip of mind - Thanks Pgras
for(int i=0;i<x;i++){ //input x number of words and store..
arr[i] = in.readLine();
}
for(i=x-1;i>=0;i--){ //Display words in reverse order
System.out.println(arr[i]);
}