Java Reading Strings to a 2D Boolean Array - java

I am trying to read a txt file which consists of # and spaces to a 2D boolean array, so that technically a # represents true and a space represents false.
With the help of similar posts i got together a code, although they were reading integers to an array.
My code is:
public static void main(String[] args) {
String x;
String y;
Scanner fileName = null;
try {
fileName = new Scanner(new File("C:/Users/USER/Desktop/hashtag.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
x = fileName.nextLine();
y = fileName.nextLine();
boolean[][] cells = new boolean[x][y];
String finalX = fileName.nextLine();
String finalY = fileName.nextLine();
cells[finalX][finalY] = true;
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
if (cells[i][j])
System.out.print("#");
else
System.out.print(" ");
}
System.out.println();
}
}
In my code where I have written boolean[][] cells = new boolean[x][y];
It says the [x] and [y] requires an int, but found a string. The same issue is for cells[finalX][finalY] = true;
I tried parsing i.e. Integer.parseInt(x) however this gets me an error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "#####################"
At what point is my issue? If I parse to an Int, then it can't read the # correct?

I think this would solve it:
1- read each line of file until the end of it to get the number of cells rows which is n then take length of any String line to get number of columns which is m.
2- create boolean array cells[n][m].
3- read file line by line and put each line in String variable and iterate over the string variable characters if character is # put true in cells array otherwise put false.
String line="";
int n=0;
while(fileName.hasNextLine()){
line = fileName.nextLine();
n++;
}
int m = line.length();
boolean[][] cells = new boolean[n][m];
// initialize Scanner to read file again
Scanner in = new Scanner(new File("C:/Users/USER/Desktop/hashtag.txt"));
int i=0;
while(in.hasNextLine()){
line = in.nextLine();
for(int j=0; j < line.length(); j++){
char c = line.charAt(j);
if(c == '#'){
cells[i][j] = true;
}
else{
cells[i][j] = false;
}
}
i++;
}

You have many mistakes in code and this approach is definitely wrong, you don't even save values that you read from file inside array. Also this code is simply not how you do it, for reading files where you don't know length of file you want to use Lists where you don't need to specify number of elements that list will take(its possible to do get semi-working solution with arrays but there is no point of learning something that is simply wrong). Before even trying to work with files you should learn more basic things, you don't even initialize your arrays properly, you use string for size and index which is causing those issues you mentioned, another beginner mistake is trying to parse non-integer string to int(you are trying to convert ############ to int which is impossible, you can only use this if you know that string is an integer like 1 or 5 or 1000).
So my answer to your question is to just go slowly and learn basics then add new stuff step by step instead just rushing with it.

It says the [x] and [y] requires an int, but found a string. The same
issue is for cells[finalX][finalY] = true;
I tried parsing i.e. Integer.parseInt(x) however this gets me an
error: Exception in thread "main" java.lang.NumberFormatException: For
input string: "#####################"
One approach you could do is first read the entire file.
Example:
List<String> tempList = new ArrayList<>();
while (fileName.hasNextLine()) {
String line = fileName.nextLine();
tempList.add(line);
}
then you can do this:
boolean[][] cells = new boolean[tempList.size()][tempList.get(0).length()];
note - this solution assumes the length() of each line is the same and the columns of each line is the same.
Also, why do you need to perform this outside the loop?
cells[finalX][finalY] = true;
you should remove that line and let the loop do all the work to determine what's # or ' '. Also, your if condition doesn't seem to be doing the correct operation. Consider implementing this approach and then go on from there.

Related

Java: Reading lines from a file when not all lines have a new line

I'm working on a program that opens a data file and reads the file line by line using a while loop to store data in a binary search tree. My only problem though is I'm not sure how to handle the loop condition, as the last line of the file does not have a new line character. I usually use hasNextLine() with a scanner for reading through a file, but this throws errors in my program, and I can't use hasNext() because I need to grab the entire line and not just pieces of it. What would be the best way to go about this?
public static BinaryTree getInventory(BinaryTree tree, Scanner input) {
String line, title = "";
int available = -1, rented = -1, comma = 0;
boolean quote = true;
// While not the end of file
while (input.hasNextLine()) {
line = input.nextLine();
for (int i = 1; i < line.length(); i++) {
if (line.charAt(i) == '"') {
title = line.substring(1, i);
comma = i + 1;
quote = false;
i++;
}
else if (line.charAt(i) == ',' && !quote) {
available = Integer.parseInt(line.substring(comma + 1, i - 1));
comma = i;
i++;
}
else if (i + 1 == line.length()) {
rented = Integer.parseInt(line.substring(comma + 1, i));
}
}
tree.insert(new Node(title,available,rented));
}
return tree;
}
You can avoid the need of hasNext() by catching NoSuchElementException. Also given the structure of your file (which seems to be "title",XX,YY) you an avoid looping over line characters with a code like this
try {
while (true) {
String line = input.nextLine();
int rdquo = line.indexOf('"', 1);
String title = line.substring(1, rdquo);
String[] avail = line.substring(rdquo+2).split(",");
tree.insert(new Node(title, Integer.parseInt(avail[0]) , Integer.parseInt(avail[1]));
}
} catch (NoSuchElementException reachedEndOfFile) { }
The accepted answer should solve your problem just fine, but I think it's worth pointing something out so you (or people learning from your post) correctly understand how Scanner works.
Given an input source like Line 1\nLine 2, where Line 2 does not end in a newline character, the following code will print both lines without throwing any errors.
while (input.hasNextLine()) {
System.out.println(input.nextLine());
}
This will also print both lines.
while (input.hasNext()) {
System.out.println(input.nextLine());
}
Given your example code, I think it's most likely that one of your titles contained a comma, which would lead to Integer.parseInt trying to parse some text that isn't an integer. When asking for help troubleshooting code that throws an error, it's helpful to share the exception and possibly a stack trace.

What is "int" in this line?

I'm attempting to write an array inside a for loop that doesn't seem to make any sense with the error.
String[][] userName;
userName = new String[3][4];
for(int x=1; x<= 4; x++) {
for(int y=-1; y <= 3; y++) {
System.out.println("Enter student name for row "+x+"column "+y+" ==>");
userName[x-1][y-1] = (String) System.in.read();
}
}
For the line:
userName[x-1][y-1] = (String) System.in.read()
it gives an error:
Incompatible types: int cannot be converted to String
But what in that line is classified as int? The only ones I know are the [x-1][y-1], but they're numbers to find the place in the array, also, I even deleted them, and it still says the same error.
What is classified as int, and how do I fix this error?
because System.in.read() will read bytes will return the value within range of 0-255 so you don't need it , you want to read String then either use Scanner or Streams
Scanner scan =new Scanner(System.in);
for(int x=1; x<= 4; x++) {
for(int y=-1; y <= 3; y++) {
System.out.println("Enter student name for row "+x+"column "+y+" ==>");
userName[x-1][y-1] = scan.read();
}
}
Scanner (import java.util.Scanner)
Scanner scan =new Scanner(System.in);
scan.read(); // read the next word
scan.readLine(); // read the whole line
or
Streams
InputStreamReader r=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(r);
String str=br.readLine();
Scanner is easy , comes with lot of functionality link to doc , Streams can be used to read bulk data which sometimes can't be read by scanner
1 for(int x=1; x<= 4; x++)
2 {
3 for(int y=-1; y <= 3; y++)
4 {
5 System.out.println("Enter student name for row "+x+"column "+y+" ==>");
6 userName[x-1][y-1] = (String) System.in.read();
7 }
8 }
Lets split this loop bit by bit.
On line 6, You are taking an Integer input through System.in.read() line, but your array is basically String datatype! So, you cast it to String. however, you cannot really insert int to a string without Integer.toString(System.in.read()). It's the normal way! However, the easiest way would be
userName[x-1][y-1] = "" + System.in.read();
Java reads a line from right to left. So it will take an input and append it to an empty String and then put it inside userName array!.
(Thanks to Pavneet Singh for noticing me)
(Thanks to Erwin Bolwidt for correcting me out. I did not notice it was String!)
Or, you can use Scanner class.
To do that you will need add the following codes.
add the following before your class line (public class)
import java.util.Scanner;
Then when you class starts inside public static void main(..), on the first line or in any convenient line before function, you will write the following line
Scanner sc = new Scanner(System.in);
It initializes the scanner. Then you can use the scanner class!
userName[x-1][y-1] = sc.next();
See through scanner class, you will need to specify the data type you will be providing! So, if you/user provides String or float or boolean value, it will throw an error and program will end/crash! Pretty effective, if you are trying to avoid wrong datatype.
Finally, you probably have an error in your loop declaration on line 3.
You can run the loop from y = -1 but, in Java, array indexes starts from 0. So, there is no index on y - 1 = - 1 - 1 = -2, it will throw an error! To avoid this all you have to do is, declare your loop from y = 1.
for(int y = 1, y <= 3; y++)
Happy programming! Cheers!
Before using System.in.read() you should have done some research on it. The System.in.read() method reads bytes of data from input stream and return the data as integer. So you can only use an integer or a character variable to store the data. String variables cannot store the data returned by the method System.in.read(). And this is the reason why you get the exception
incompatible types: int cannot be converted to String
And also use a try catch block when you are using System.in.read() method.

excess spaces in front of printed text java

I am trying to write a program to reverse the letters/words in an inputted string, I thought I finally had it but I can't figure out why there are so many excess spaces in front of my output text. Any help would be greatly appreciated.
Also on a side note I attempted to make the scope of the array an incremented variable but it would not run, however I can use an incremented variable for the index position without any issues; why is that?
This is what I have so far and it seems to do exactly what I want it to do minus all the excess white space in front of the output.
Scanner in = new Scanner(System.in);
System.out.println("please enter string");
String strName = in.nextLine();
int ap = 0;
char strArray[] = new char[99];
for(int i=0;i < strName.length();i++)
{
strArray[ap] = strName.charAt(i);
ap++;
}
for (int e=strArray.length-1;e >= 0;e--)
{
System.out.print(strArray[e]);
}
Try this
Scanner in = new Scanner(System.in);
System.out.println("please enter string");
String strName = in.nextLine();
int ap = 0;
char strArray[] = new char[strName.length()];
for(int i=0;i < strName.length();i++)
{
strArray[ap] = strName.charAt(i);
ap++;
}
for (int e=strArray.length-1;e >= 0;e--)
{
System.out.print(strArray[e]);
}
The issue is you are initializing that char array to size 99. For a string of size 4... we have to print 95 nulls THEN the 4 chars in reverse order. This will be fixed by initializing the array to the actual size of the input string. No nulls to print then (printing nulls results in a white space).
Also on a side note I attempted to make the scope of the array an incremented variable but it
would not run, however I can use an incremented variable for the index position without any
issues; why is that?
Hmmm. Not sure what you mean? The word "scope" has specific meaning in CS that I don't think is the meaning you are referring to!

Cannot assign a substring from a file to my array

I have a file with 50 states and capitals in this format:
Alabama,Tallahasee,
Wisconsin,Madison,
........
I am trying to assign the states and capitals to seperate arrays and I am having a problem with the for loop. My code is as follows:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class StatesAndCapitals {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream is = new FileInputStream("capitals.txt");
Scanner input = new Scanner(is);
String[] states = new String[50];
String[] capitals = new String[50];
for (int i = 0; i < states.length; i++){
int a = states[i].lastIndexOf(",");
String states1 = states[i].substring(0, a);
states[i] = states1;
input.nextLine();
}//end for loop
System.out.println(states);
}
}
The error I am getting is
Exception in thread "main" java.lang.NullPointerException
at StatesAndCapitals.main(StatesAndCapitals.java:12)
any help would be appreciated.
When you do
states[i].lastIndexOf(",");
you're analyzing the content of states[i]. But that is your destination array, and not the source containing the text. The source is what is returned from input.nextLine(), which should be the first thing you should do at each iteration:
for (int i = 0; i < states.length; i++){
String currentLine = input.nextLine();
// now extract the data from current line, and store them in the arrays.
}
for (int i = 0; i < states.length; i++){
int a = states[i].lastIndexOf(",");
String states1 = states[i].substring(0, a);
states[i] = states1;
input.nextLine();
}//end for loop
This whole loop is backwards. When you first enter at i = 0 you attempt to take a substring of your states array which has never seen any sort of assignment. You then work on that substring within the loop before ending with input.nextLine(); which is never actually used.
The input variable, when used correctly will actually hold data from the file you open and will allow you to manipulate strings with substring. You need to reorder and fix your loop.
The default value for an object is null.
String[] states = new String[50]; //<-- you declare an array that can holds 50 Strings but they're actually null if you don't initialize them.
So when doing states[i].lastIndexOf(","); it throws a NPE.
Same behavior for your capitals array.
Read the Default Values section.
You need to store the datas in a String variable first :
for (int i = 0; i < states.length; i++){
String data = input.nextLine();
// Now process with data and add corresponding parts to states and capitals array
}//end for loop
And then process on this String and add it to the corresponding array.
Not that if you don't have enough lines in your file (less than 50), it will throw java.util.NoSuchElementException because no more lines are found.
You can add this condition to the loop : for (int i = 0; i < states.length && input.hasNextLine(); i++){
When you will get this working correctly, I suggest you to deal with a List.

Why did I get an "ArrayIndexOutOfBoundsException"?

I'm pretty new to programming and working on an assignment for class. Now, I'm not asking for anyone to write my code for me but I'm stuck with a runtime error. In the assignment we need to read a file, use the first line, "15", to initialize the size of an array, and proceed to fill the array with the information from each line.
edit: I didn't want to post all of the code because I thought it would look too long but because of the downvotes for being vague, here it goes.
File:
15
produce,3554,broccoli,5.99,1
produce,3554,broccoli,5.99,1
produce,3555,carrots,2.23,0.25
produce,3555,carrots,2.23,0.25
produce,3555,carrots,2.23,0.25
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2346,toilet paper,12.99,4 rolls
cleaning,2346,toilet paper,12.99,4 rolls
cleaning,2335,windex,2.25,1 mini sprayer
cleaning,1342,wipes,3.99,10 units
cleaning,1342,wipes,3.99,10 units
produce,3546,lettuce,2.99,0.5
My Error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15
at Inventory.readFile(Inventory.java:45)
at Inventory.<init>(Inventory.java:12)
at Supermarket.main(Supermarket.java:3)
Class with the Line 45 in Question (line 45 is commented, scroll to the right)"
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class Inventory{
Product[] list;
String[] invData;
private int i = 0;
public int count;
public Inventory (String f){
readFile(f);
}
public int indexOfProduct(int code){
for(i=0; i<list.length; i++){
if (list[i] != null)
if (list[i].getCode() == code)
return i;
}
return -1;
}
public Product delete(int pos){
Product temp = new Product();
temp = list[pos];
list[pos] = null;
return temp;
}
public void readFile(String fileName){
try{
File invList = new File (fileName);
Scanner s = new Scanner(invList);
int itemCount = s.nextInt();
list = new Product[itemCount];
count = itemCount;
while (s.hasNext()){
String line = s.nextLine();
invData = line.split(",");
if (invData[0].equals("produce")){
list[i] = new Produce(invData[1], invData[2], invData[3], invData[4]); // This is Line 45, Where the error occurs
} else if(invData[0].equals("cleaning")){
list[i] = new Cleaning(invData[1], invData[2], invData[3], invData[4]);
}
i++;
}//end of while loop
} catch (FileNotFoundException Abra) {
String error = Abra.getMessage();
System.out.println(error);
}
} // end of method
public Product findCode(int c){
for(int i=0; i<list.length;i++)
if(list[1].getCode() == c)
return list[i];
return null;
}//end of method
}//end of class
Why did I get an "ArrayIndexOutOfBoundsException"? I hope someone can point out the flaw in my logic so I don't repeat it again.
Your issue is clearly with the use of i, as that is the only variable index on that line, and the out of range index is "15", which is just past the end of your 15-item array. So, couple of issues, all surrounding the use of i:
As nhellwig mentioned, be sure that i is actually initialized to 0 before calling this function.
Additionally, you're putting a lot of faith in the consistency of the item number in the file and the actual number of items. You should either produce a warning and stop trying to store items in the array if i >= itemCount, or use a container like an ArrayList that can grow to accommodate new items instead of a fixed size array.
Edit: Also, I should point out that you increment i whether you read an item or not, which means even blank lines will increment i, causing gaps in your list or array overruns. Since itemCount is the number if items, you should stick to that and only increment i if you read an actual item.
In that same spirit, you should verify that invData.length == 5 after you call split(), because a misplaced comma, etc. in your file may also end up with an OOB error. Granted, for your project, it's probably OK to make assumptions about the number of elements in a line that starts with "produce" or "cleaning", but in general it's important to be cautious with data coming from a user-created file.
I found the answer to be that I needed an "s.nextLine();"
Because I used "s.nextInt();" the pointer was just hangin around at the end of "15" in my file. Then, when the first line in the While loop "String line = s.nextLine();" executed the pointer moved from the end of 15 to before the p in produce in the 2nd line of the list file.
The working method looks like this:
public void readFile(String fileName){
try{
File invList = new File (fileName);
Scanner s = new Scanner(invList);
int itemCount = s.nextInt();
s.nextLine(); // This is the new line that made it work
list = new Product[itemCount];
count = itemCount;
while (s.hasNext()){
String line = s.nextLine(); //moves file pointer over one
invData = line.split(",");
if (invData[0].equals("produce")){
list[i] = new Produce(invData[1], invData[2], invData[3], invData[4]);
} else if(invData[0].equals("cleaning")){
list[i] = new Cleaning(invData[1], invData[2], invData[3], invData[4]);
}
i++;
}//end of while loop
} catch (FileNotFoundException Abra) {
String error = Abra.getMessage();
System.out.println(error);
}
} // end of method
How many times do you call readFile? You should have i = 0; at the beginning of the function.
"i" should not be a global value but should be a method local variable, initialized to zero.

Categories