Getting null pointer exception while inserting into two dimensional array of Strings - java

I have file named input1.txt with contents as below:
a b c d
b d
c d
d e
I want to read it and put them in 2-dimensional array of Strings. I have written code for it. But it is showing NULL POINTER EXCEPTION. Where may be the error? Below is my code:
I am getting the exception in line graphNodes[i][j] = s;
BufferedReader br = null;
BufferedReader cr = null;
int lines = 0;
try {
br = new BufferedReader(new FileReader(filename));
try {
while (br.readLine() != null) {
lines++;
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
List<String> nodes = new ArrayList<String>();
String[][] graphNodes = new String[lines][];
String[] line = new String[lines];
int i = 0;
int j = 0, x = 0;
try {
cr = new BufferedReader(new FileReader(filename));
while (cr.readLine() != null) {
line[x] = cr.readLine();
System.out.println("Line is: " + line[x]);
String[] letters = line[x].split(" ");
for (String s : letters) {
System.out.println("Letter is " + s);
graphNodes[i][j] = s;
j++;
}
i++;
x++;
}
} catch (IOException e) {
e.printStackTrace();
}

the graphNodes is missing column length
String[][] graphNodes = new String[lines][];
in your problem, once you get letters, you can initialize column of 2d array
String[] letters = line[x].split(" ");
graphNodes[i] = new String[letters.length];

You need to instantiate graphNodes[i] before accessing its j index.

I believe you're having issues with the following bit of code:
try {
cr = new BufferedReader(new FileReader(filename));
while (cr.readLine() != null) {
line[x] = cr.readLine();
System.out.println("Line is: " + line[x]);
String[] letters = line[x].split(" ");
for (String s : letters) {
System.out.println("Letter is " + s);
graphNodes[i][j] = s;
j++;
}
i++;
x++;
}
}
This while statement says "while cr.readLine() != null" and at that very moment it read the first line of the file, compared it with null, and it wasn't null so it enters the loop. You then told it to set line[x] equal to cr.readLine() which it then reads the next line of the file, and sets it equal to line[x]. Thus skipping the first line of code doing nothing more with it than using it to check the while loop condition.
I think what you want in your while loop is something like this
try {
cr = new BufferedReader(new FileReader(filename));
for(String lineValue = cr.readLine(); lineValue != null; x++, lineValue = cr.readLine()) {
line[x] = lineValue;
System.out.println("Line is: " + line[x]);
String[] letters = line[x].split(" ");
for (String s : letters) {
System.out.println("Letter is " + s);
graphNodes[i][j] = s;
j++;
}
i++;
}
}
But as someone mentioned previously, You need to declare the size of your 2 dimensional array. For the sake of this loop I just made it String[lines][100] but you'll want to adjust that to meet your needs (however long you anticipate your longest line of letters to be.

Well for one, you are not specifying a value for the second dimension: String[][] graphnodes = new String[lines][].
This means you are basically trying to set s to a value that cannot exist.
you might try defining String[] letters first then doing something like String[][] graphnodes = new String[lines][letters.getLength()];
also,
while (cr.readLine() != null) should be while (cr.hasNextLine())
your code would also look a lot cleaner if you did something like:
for (int i = 0, j = 0, x = 0; cr.hasNextLine(); i++, x++) {
line[x] = cr.readLine();
System.out.println("Line is: " + line[x]);
String[] letters = line[x].split(" ");
for (String s : letters) {
System.out.println("Letter is " + s);
graphNodes[i][j] = s;
j++;
}
}

First of All you don't need to read the files twice. Once to get the number of lines and the other to get the actual data.
You need to read the lines and put them directly in a List. Then you can do whatever you need with that list.

Related

Doesn't save the words in array

i've got a propably simple question. I try to read the file and i want to add each single word to my array "phrase". The problem occures in for loop. I got the exception "index 0 out of bounds for length 0".
Can you please help me with that?
String [] tokens;
String line;
String hash = " ";
int n = 0;
String [] phrase = new String [n];
public void loadFile()
{
try
{
#SuppressWarnings("resource")
BufferedReader br = new BufferedReader(new FileReader("z3data1.txt"));
while((line = br.readLine()) != null)
{
tokens = line.split("[ ]");
n += tokens.length;
}
for(int j = 0; j<tokens.length; j++)
{
phrase[j] = tokens[j];
}
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
A couple observations.
you are getting the error because your array is not large enough and the index j is exceeding its size.
you keep overwriting tokens in the while loop. The while loop needs to encompass the copying of the tokens to the phrase array.
So try the following:
while((line = br.readLine()) != null) {
tokens = line.split("[ ]");
n += tokens.length; // don't really need this.
//starting offset to write into phrase
int len = phrase.length;
phrase = Arrays.copyOf(phrase,phrase.length + tokens.length);
for(int j = 0; j<tokens.length; j++) {
phrase[j + len] = tokens[j];
}
}
This statement
phrase = Arrays.copyOf(phrase,phrase.length + tokens.length)
Copies the contents of phrase and increases the array size to handle the writing of tokens.
Another (and probably preferred) alternative is to use a List<String> which grows as you need it.
List<String> phrase = new ArrayList<>();
for(int j = 0; j<tokens.length; j++) {
phrase.add(tokens[j]);
}
// or skip the loop and just do
Collections.addAll(phrase,tokens);
One observation. I don't know what you are splitting on but your split statement looks suspicious.
You're setting n to 0, so phrase is also of length 0 when you say String[] phrase = String[n]. Therefore, you can't add anything to it.
If you want something of variable length, you can use an ArrayList. In the code below, you can directly use Collections.addAll to split up the line and put everything into the phrase ArrayList.
String line;
//Note that you can get rid of tokens here, since it's being inlined below
ArrayList<String> phrase = new ArrayList<>();
public void loadFile()
{
try
{
#SuppressWarnings("resource")
BufferedReader br = new BufferedReader(new FileReader("z3data1.txt"));
while((line = br.readLine()) != null)
{
//No need for a for-loop below, you can do everything in one line
Collections.addAll(phrase, line.split("[ ]"));
}
}
catch(IOException ex)
{
ex.printStackTrace();
}
}

Removing last line and white spaces while writing arrays to file

Writing data in a file with loop line by line will cause the last line to be 'newline'. Consider this:
try {
outFile = new BufferedWriter(new FileWriter(outFileName));
for (int i = 0; i < some_condition; i++) {
for (String record: aLine) {
outFile.write(record + " ");
}
outFile.write("\n");
}
} catch(IOException e) {
System.out.println("found error!");
}
Also the last item in each row is " ". What is the efficient way to trim such white spaces and newline?
I can divide the loop to 0...n-2 and n-1 but is not very good for big codes. I am looking for some file based solutions like this:
try {
outFile = new BufferedWriter(new FileWriter(outFileName));
for (int i = 0; i < some_condition; i++) {
for (String record: aLine) {
outFile.write(record + " ");
}
outFile.REMOVE_LAST_CHARACTER; // trim " "
outFile.write("\n");
}
} catch(IOException e) {
System.out.println("found error!");
}
outFile.REMOVE_LAST_LINE;
Is that possible?
Append it to StringBuilder and then at last remove the last character by trimming the String or you can manually check in for loop while appending " ". For \n newline character, You can append every line to a main StringBuilder which keeps track of whole file and trim the extra space at last.
StringBuilder all_lines = new StringBuilder(); //To store every line
for (int i = 0; i < some_condition; i++) {
StringBuilder line = new StringBuilder();
for (String record: aLine) {
line.append(record).append(" "); //To store every words
}
all_lines.append(line.toString().trim());
all_lines.append("\n");
}
outFile.write(all_lines.toString().trim());
outFile.close();
You can write the space and new line before the record, here is an example:
try {
outFile = new BufferedWriter(new FileWriter(outFileName));
for (int i = 0; i < some_condition; i++) {
if(i!=0){
outFile.write("\n");
}
boolean firstRecord = true;
for (String record: aLine) {
outFile.write((firstRecord ? "" : " ") + record);
firstRecord = false;
}
}
} catch(IOException e) {
System.out.println("found error!");
}

InputStream reading file and counting lines/words

I'm working on a project and I'm trying to count
1) The number of words.
2) The number of lines in a text file.
My problem is that I can't figure out how to detect when the file goes to the next line so I can increment lines correctly. Basically if next is not a space increment words and if next is a new line, increment lines. How would I do this? Thanks!
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNext()) {
if (f.next().equals("\n")) {
lines++;
} else if (!(f.next().equals(" "))) {
words++;
}
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}
Try this:
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNextLine()) {
String line = f.nextLine();
lines++;
for (String token : line.split("\\s+")) {
if (!token.isEmpty()) {
words++;
}
}
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}
Do you have to use InputStream? (Yes) It is better to use a BufferedReader with an InputStreamReader passed in so you can read the file line by line and increment while doing so.
numLines = 0;
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null)
{
numLines++;
// process the line.
}
}
Then to count the words just split the string using a regular expression that finds whitespaces. myStringArray = MyString.Split(MyRegexPattern); will then return a String[] of all the words. Then all you do is numWords += myStringArray.length();
You can use an InputStreamReader to create a bufferedreader which can read a file line by line:
int amountOfLines = 0;
try {BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))} catch (Exception e) {e.printStackTrace();}
String line;
while ((line = br.readLine()) != null{
numLines++;
// process the line.
}
You can then use the split(String) method to separate every part
Try following:
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNextLine()) {
String line = f.nextLine();
String[] arr = line.split("\\s");
words += arr.length;
lines++;
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}

To print the given rows of string into columns

I have *.txt file with first row as name,address,mail id and second line with the values. I have to print this into two columns,the first one with the headings and second with the value using Java. how do I do this?
public class ReadFile1 {
public static void main(String[] args) {
BufferedReader br=null;
String sCurrentLine = null;
String delimiter = ",";
String[] filetags;
try {
br = new BufferedReader(new FileReader("path\\Read.txt"));
sCurrentLine = br.readLine();
StringBuffer result = new StringBuffer();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String line = null;
try {
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
filetags = line.split(delimiter);
for(int i = 0;i < line.length(); i++)
{
System.out.println("****" +sCurrentLine);
String[] s = line.split(",");
for(int j = i-1; j<line.length();j++)
{
System.out.println("##############"+Arrays.toString(s));
}
}
}
}
This is what I tried. Ex: I have a file say,
line1) name,email,mobile and second
line2) john,j#abc.com,9876
line3) max,max#xyz.com,1234
Now, I need to print:
name john
email john#abc.com
moblie 9876
name max
email max#xyz.com
mobile 1234
Below is one way you may be able to get what you want, It is similar to how you have attempted but slightly more refined.
The File:
name,email,mobile and second
john,j#abc.com,9876
max,max#xyz.com,1234
The code:
//File is on my Desktop
Path myFile = Paths.get(System.getProperty("user.home")).resolve("Desktop").resolve("tester.txt");
//Try-With-Resources so we autoclose the reader after try block
try(BufferedReader reader = new BufferedReader(new FileReader(myFile.toFile()))){
String[] headings = reader.readLine().split(",");//Reads First line and gets headings
String line;
while((line = reader.readLine()) != null){//While there are more lines
String[] values = line.split(","); //Get the values
for(int i = 0; i < values.length; i++){//For each value
System.out.println(headings[i] + ": " + values[i]);//Print with a heading
}
}
} catch (IOException io) {
io.printStackTrace();
}
Good Luck!
Something like this should do the trick.
Read the file and store each line in a list.
Iterate through the list of lines
If it is safe to assume the first line will always be the title line, take the input and store it in a collection.
For the rest of the lines, split on the comma and use the index of the splitter array to refer to the title column.
List <String> lines = new ArrayList<String>();
Scanner scanner = new Scanner(new File("FileName.txt"));
while(scanner.hasNextLine()){
String line = scanner.nextLine();
lines.add(line);
}
scanner.close();
int lineNo = 0;
List <String> title = new ArrayList<String>();
for(String line : lines){
if(lineNo == 0){
String [] titles = line.split(",");
for(String t : titles){
title.add(t);
}
lineNo++;
}
else{
String input = line.split(",");
for(int i = 0; i<input.length; i++){
System.out.println(title.get(i) + ": " + input[i]);
}
lineNo++;
}
}

Java Reading 2D array in from file, numbers separated by comma

This is some code that I found to help with reading in a 2D Array, but the problem I am having is this will only work when reading a list of number structured like:
73
56
30
75
80
ect..
What I want is to be able to read multiple lines that are structured like this:
1,0,1,1,0,1,0,1,0,1
1,0,0,1,0,0,0,1,0,1
1,1,0,1,0,1,0,1,1,1
I just want to essentially import each line as an array, while structuring them like an array in the text file.
Everything I have read says to use scan.usedelimiter(","); but everywhere I try to use it the program throws straight to the catch that replies "Error converting number". If anyone can help I would greatly appreciate it. I also saw some information about using split for the buffered reader, but I don't know which would be better to use/why/how.
String filename = "res/test.txt"; // Finds the file you want to test.
try{
FileReader ConnectionToFile = new FileReader(filename);
BufferedReader read = new BufferedReader(ConnectionToFile);
Scanner scan = new Scanner(read);
int[][] Spaces = new int[10][10];
int counter = 0;
try{
while(scan.hasNext() && counter < 10)
{
for(int i = 0; i < 10; i++)
{
counter = counter + 1;
for(int m = 0; m < 10; m++)
{
Spaces[i][m] = scan.nextInt();
}
}
}
for(int i = 0; i < 10; i++)
{
//Prints out Arrays to the Console, (not needed in final)
System.out.println("Array" + (i + 1) + " is: " + Spaces[i][0] + ", " + Spaces[i][1] + ", " + Spaces[i][2] + ", " + Spaces[i][3] + ", " + Spaces[i][4] + ", " + Spaces[i][5] + ", " + Spaces[i][6]+ ", " + Spaces[i][7]+ ", " + Spaces[i][8]+ ", " + Spaces[i][9]);
}
}
catch(InputMismatchException e)
{
System.out.println("Error converting number");
}
scan.close();
read.close();
}
catch (IOException e)
{
System.out.println("IO-Error open/close of file" + filename);
}
}
I provide my code here.
public static int[][] readArray(String path) throws IOException {
//1,0,1,1,0,1,0,1,0,1
int[][] result = new int[3][10];
BufferedReader reader = new BufferedReader(new FileReader(path));
String line = null;
Scanner scanner = null;
line = reader.readLine();
if(line == null) {
return result;
}
String pattern = createPattern(line);
int lineNumber = 0;
MatchResult temp = null;
while(line != null) {
scanner = new Scanner(line);
scanner.findInLine(pattern);
temp = scanner.match();
int count = temp.groupCount();
for(int i=1;i<=count;i++) {
result[lineNumber][i-1] = Integer.parseInt(temp.group(i));
}
lineNumber++;
scanner.close();
line = reader.readLine();
}
return result;
}
public static String createPattern(String line) {
char[] chars = line.toCharArray();
StringBuilder pattern = new StringBuilder();;
for(char c : chars) {
if(',' == c) {
pattern.append(',');
} else {
pattern.append("(\\d+)");
}
}
return pattern.toString();
}
The following piece of code snippet might be helpful. The basic idea is to read each line and parse out CSV. Please be advised that CSV parsing is generally hard and mostly requires specialized library (such as CSVReader). However, the issue in hand is relatively straightforward.
try {
String line = "";
int rowNumber = 0;
while(scan.hasNextLine()) {
line = scan.nextLine();
String[] elements = line.split(',');
int elementCount = 0;
for(String element : elements) {
int elementValue = Integer.parseInt(element);
spaces[rowNumber][elementCount] = elementValue;
elementCount++;
}
rowNumber++;
}
} // you know what goes afterwards
Since it is a file which is read line by line, read each line using a delimiter ",".
So Here you just create a new scanner object passing each line using delimter ","
Code looks like this, in first for loop
for(int i = 0; i < 10; i++)
{
Scanner newScan=new Scanner(scan.nextLine()).useDelimiter(",");
counter = counter + 1;
for(int m = 0; m < 10; m++)
{
Spaces[i][m] = newScan.nextInt();
}
}
Use the useDelimiter method in Scanner to set the delimiter to "," instead of the default space character.
As per the sample input given, if the next row in a 2D array begins in a new line, instead of using a ",", multiple delimiters have to be specified.
Example:
scan.useDelimiter(",|\\r\\n");
This sets the delimiter to both "," and carriage return + new line characters.
Why use a scanner for a file? You already have a BufferedReader:
FileReader fileReader = new FileReader(filename);
BufferedReader reader = new BufferedReader(fileReader);
Now you can read the file line by line. The tricky bit is you want an array of int
int[][] spaces = new int[10][10];
String line = null;
int row = 0;
while ((line = reader.readLine()) != null)
{
String[] array = line.split(",");
for (int i = 0; i < array.length; i++)
{
spaces[row][i] = Integer.parseInt(array[i]);
}
row++;
}
The other approach is using a Scanner for the individual lines:
while ((line = reader.readLine()) != null)
{
Scanner s = new Scanner(line).useDelimiter(',');
int col = 0;
while (s.hasNextInt())
{
spaces[row][col] = s.nextInt();
col++;
}
row++;
}
The other thing worth noting is that you're using an int[10][10]; this requires you to know the length of the file in advance. A List<int[]> would remove this requirement.

Categories