Analysing text that is read from a file in Java - java

I am writing a program that analyses text that is input and calculates the average letter count.
I have it working for when text is entered by the user, but I cannot get it to work for when the text is read from a file.
public static void ReadFromFile() throws IOException {
String filename = "name.txt";
String str = new String(new char[100]);
try{
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
while ((str = br.readLine()) !=null) {
System.out.println(str + "\n");
}
br.close();
} catch(IOException e) {
System.out.println("File not found");
}
while (c != str.length()) {
if (str.charAt(c) >= 'a' && str.charAt(c) <= 'z') {
count[str.charAt(c) - 'a']++;
}
c++;
}
for (c = 0; c<26;c++){
if (count[c] !=0){
double num = count[c];
double denom = str.length();
double average = num / denom;
System.out.print((char) (c + 'a') + " occurs " + count[c] + " times in the entered string. Average is ");
System.out.println(average);
}}}}
I keep getting an error that says
Exception in thread "main" java.lang.NullPointerException
at MainMenu.ReadFromFile(MainMenu.java:79)
at MainMenu.main(MainMenu.java:25)
Any help would be greatly appreciated
Thanks

You are reading the entire file in, line by line and printing it to System.out
After you have finished that, you then try to process the data, but you've already finished reading in the file, hence str is 'null' and your program dies.

Earlier in your code, you have this loop:
while ((str = br.readLine()) != null) {
System.out.println(str + "\n");
}
This will read lines from your file while str is not null.
That means that when it stops, str is null.
Since you don't give str a non-null value after that, you get an NPE when you try to run methods on str later in the code:
while (c != str.length()) { // str is null here!
if (str.charAt(c) >= 'a' && str.charAt(c) <= 'z') {
count[str.charAt(c) - 'a']++;
}
c++;
}
My guess from looking at your code is that you want to collect information about each line in the file. To do this, instead of just printing each line, move your counting logic inside the loop which is reading the file:
// read each line from the file
while ((str = br.readLine()) != null) {
System.out.println(str + "\n");
// collect character data for this line
while (c != str.length()) {
if (str.charAt(c) >= 'a' && str.charAt(c) <= 'z') {
count[str.charAt(c) - 'a']++;
}
c++;
}
}
Then process the count array later in the code as you are already doing.

Related

How can i use splitter ^ in java

I have a problem with my java program. I have to read lines from a file, the form of these lines is:
1#the^cat#the^dog#the^bird#^fish#bear
2#the^cat#the^dog#the^bird#^fish#bear
and print all, accept the "#" and "^" at textfields in my GUI. The "^" must appear in case there in not article. For exaple ^fish, i have to print it as ^fish but the^dog i have to print the dog.
As far i can read and print the lines in the textfields but i can't find a way to skip the "^" between the words.
Here is my code:
try {
FileReader file = new FileReader("C:\\Guide.txt");
BufferedReader BR = new BufferedReader(file);
boolean eof = false;
int i=0;
while (!eof) {
String line = BR.readLine();
if (line == null)
eof = true;
else {
i++;
System.out.println("Parsing line "+i+" <"+line+">");
String[] words = line.split("#");
if (words.length != 7) continue;
number=words[0];
onomastiki=words[1];
geniki=words[2];
aitiatiki=words[3];
klitiki=words[4];
genos=words[5];
Region=words[6];
E = new CityEntry(number,onomastiki,geniki,
aitiatiki,klitiki,
genos,Region);
Cities.add(E);
}
You can try something like this.
FileReader file = new FileReader("C:\\\\Users\\\\aq104e\\\\Desktop\\\\text");
BufferedReader BR = new BufferedReader(file);
boolean eof = false;
int i = 0;
while (!eof) {
String line = BR.readLine();
if (line == null)
eof = true;
else {
i++;
System.out.println("Parsing line " + i + " <" + line + ">");
String[] words = line.split("#");
for (int j = 0; j < words.length; j++) {
if(words[j].contains("^")) {
if(words[j].indexOf("^") == 0) {
// write your code here
//This is case for ^fish
}else {
// split using ^ and do further manipulations
}
}
}
}
}
Let me know if this works for you.
That is gonna work, but it is not best way)
foreach(String word : words){
if(word.contains"the"){
word.replace("^"," ");
}
}

How to continue processing a file when I reach a null String [duplicate]

This question already has an answer here:
What is a StringIndexOutOfBoundsException? How can I fix it?
(1 answer)
Closed 4 years ago.
I'm trying to read in a file that contains a sequence of DNA. And within my program I want to read in each subsequence of that DNA of length 4, and store it in my hashmap to count the occurence of each subsequence. For example if I have the sequence CCACACCACACCCACACACCCAC, and I want every subsequence of length 4, the first 3 subsequences would be:
CCAC, CACA, ACAC, etc.
So in order to do this I have to iterate over the string several times, here is my implementation
try
{
String file = sc.nextLine();
BufferedReader reader = new BufferedReader(new FileReader(file + ".fasta"));
Map<String, Integer> frequency = new HashMap<>();
String line = reader.readLine();
while(line != null)
{
System.out.println("Processing Line: " + line);
String [] kmer = line.split("");
for(String nucleotide : kmer)
{
System.out.print(nucleotide);
int sequence = nucleotide.length();
for(int i = 0; i < sequence; i++)
{
String subsequence = nucleotide.substring(i, i+5);
if(frequency.containsKey(subsequence))
{
frequency.put(subsequence, frequency.get(subsequence) +1);
}
else
{
frequency.put(subsequence, 1);
}
}
}
System.out.println();
line = reader.readLine();
}
System.out.println(frequency);
}
catch(StringIndexOutOfBoundsException e)
{
System.out.println();
}
I have a problem when reaching the end of the string, it won't continue to process due to the error. How would I go about getting around that?
You are calling substring(i, i + 5). At the end of the string i + 5 goes out of bounds. Let's say your string is "ABCDEFGH", length 8, your loop will go from i = 0 to i = 7. When i reaches 4 substring(4, 9) cannot be computed and the exception is raised.
Try this:
for(int i = 0; i < sequence - 4; i++)
You can directly read each line and extract first 4 sub-chars without
the need to splitting it up each time when you read a line.
The error you are getting because when the Program is looping through the splitted characters then it is possible that there are less than 4 characters left altogether at the end to be extracted. Less than 4 chars are responsible which is throwing the error. e.g. suppose you have a line CCACACC then grouping in 4 chars you would get 1st group as complete i.e., CCAC and 2nd group as ACC which is incomplete. So in your code when the line nucleotide.substring(i, i+5); is encountered then probably there is no group of complete 4 characters left at the end that can be extracted and hence the Program throws error. And to extract 4 chars you need to add 4, not 5.
So the work around the code will be to put the extraction line in a try block as given below in the edited code. Replace the loop body with the below code.
while(reader.hasNextLine())
{
line = reader.nextLine();
for(int i = 0; i < line.length; i++)
{
String subsequence = "";
// put the extract operation in a try block
// to avoid crashing
try
{
subsequence = nucleotide.substring(i, i+4);
}
catch(Exception e)
{
// just leave blank to pass the error
}
if(frequency.containsKey(subsequence))
{
frequency.put(subsequence, frequency.get(subsequence) +1);
}
else
{
frequency.put(subsequence, 1);
}
}
Based on the title of your post...try changing the condition for your while loop. Instead of using the current:
String line = reader.readLine();
while(line != null) {
// ...... your code .....
}
use this code:
String line;
while((line = reader.readLine()) != null) {
// If file line is blank then skip to next file line.
if (line.trim().equals("")) {
continue;
}
// ...... your code .....
}
That would cover handling blank file lines.
Now about the StringIndexOutOfBoundsException exception you are experiencing. I believe by now you already basically know why you are receiving this exception and therefore you need to decide what you want to do about it. When a string is to be split into specific length chunks and that length is not equally divisible against the overall length if a specific file line characters then there are obviously a few options available:
Ignore the remaining characters at the end of the file line. Although an easy solution it's not very feasible since it would produce incomplete data. I don't know anything about DNA but I'm certain this would not be the route to take.
Add the remaining DNA sequence (even though it's short) to the Map. Again, I know nothing about DNA and I'm not sure if even this wouldn't be a viable solution. Perhaps it is, I simply don't know.
Add the remaining short DNA sequence to the beginning of the next
incoming file line and carry on breaking that line into 4 character
chunks. Continue doing this until the end of file is reached at which
point if the final DNA sequence is determined to be short then add
that to the Map (or not).
There may of course be other options and whatever they might be it's something you will need to decide. To assist you however, here is code to cover the three options I've mentioned:
Ignore the remaining characters:
Map<String, Integer> frequency = new HashMap<>();
String subsequence;
String line;
try (BufferedReader reader = new BufferedReader(new FileReader("DNA.txt"))) {
while ((line = reader.readLine()) != null) {
// If file line is blank then skip to next file line.
if (line.trim().equals("")) {
continue;
}
for (int i = 0; i < line.length(); i += 4) {
// Get out of loop - Don't want to deal with remaining Chars
if ((i + 4) > (line.length() - 1)) {
break;
}
subsequence = line.substring(i, i + 4);
if (frequency.containsKey(subsequence)) {
frequency.put(subsequence, frequency.get(subsequence) + 1);
}
else {
frequency.put(subsequence, 1);
}
}
}
}
catch (IOException ex) {
ex.printStackTrace();
}
Add the remaining DNA sequence (even though it's short) to the Map:
Map<String, Integer> frequency = new HashMap<>();
String subsequence;
String line;
try (BufferedReader reader = new BufferedReader(new FileReader("DNA.txt"))) {
while ((line = reader.readLine()) != null) {
// If file line is blank then skip to next file line.
if (line.trim().equals("")) {
continue;
}
String lineRemaining = "";
for (int i = 0; i < line.length(); i += 4) {
// Get out of loop - Don't want to deal with remaining Chars
if ((i + 4) > (line.length() - 1)) {
lineRemaining = line.substring(i);
break;
}
subsequence = line.substring(i, i + 4);
if (frequency.containsKey(subsequence)) {
frequency.put(subsequence, frequency.get(subsequence) + 1);
}
else {
frequency.put(subsequence, 1);
}
}
if (lineRemaining.length() > 0) {
subsequence = lineRemaining;
if (frequency.containsKey(subsequence)) {
frequency.put(subsequence, frequency.get(subsequence) + 1);
}
else {
frequency.put(subsequence, 1);
}
}
}
}
catch (IOException ex) {
ex.printStackTrace();
}
Add the remaining short DNA sequence to the beginning of the next incoming file line:
Map<String, Integer> frequency = new HashMap<>();
String lineRemaining = "";
String subsequence;
String line;
try (BufferedReader reader = new BufferedReader(new FileReader("DNA.txt"))) {
while ((line = reader.readLine()) != null) {
// If file line is blank then skip to next file line.
if (line.trim().equals("")) {
continue;
}
// Add remaining portion of last line to new line.
if (lineRemaining.length() > 0) {
line = lineRemaining + line;
lineRemaining = "";
}
for (int i = 0; i < line.length(); i += 4) {
// Get out of loop - Don't want to deal with remaining Chars
if ((i + 4) > (line.length() - 1)) {
lineRemaining = line.substring(i);
break;
}
subsequence = line.substring(i, i + 4);
if (frequency.containsKey(subsequence)) {
frequency.put(subsequence, frequency.get(subsequence) + 1);
}
else {
frequency.put(subsequence, 1);
}
}
}
// If any Chars remaining at end of file then
// add to MAP
if (lineRemaining.length() > 0) {
frequency.put(lineRemaining, 1);
}
}
catch (IOException ex) {
ex.printStackTrace();
}
It is not clear at all from the question description, but I'll guess your input file ends with an empty line.
Try removing the last newline in your input file, or alternatively check against empty in your while loop:
while (line != null && !line.isEmpty())

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 269

I am writing a program that counts the number of words in a text file, but only words that have more than 2 characters in them. It was working fine before, but all of a sudden I am getting an error
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 269?
Can someone please help?
import java.io.*;
class count_words {
public static int countWords(String str)
{
int count = 1, num_of_letters = 0, final_count=1;
for (int i=0;i<=str.length()-1;i++)
{
if (str.charAt(i) == ' ' && str.charAt(i+1)!=' ')
{
if(num_of_letters <= 2)
{
count --;
}
System.out.println("count is " + num_of_letters);
num_of_letters = 0;
count++;
}
else if(str.charAt(i) == ',')
{
num_of_letters --;
}
else
{
num_of_letters++;
}
}
return count;
}
public static void main(String[] args){
//name of file to open
String fileName = "/Users/Chris/Desktop/comp 1 McPhee.txt";
//reference one line at a time
String line = null;
int num;
try
{
//Filereader reads text file in the default encoding.
FileReader filereader = new FileReader(fileName);
BufferedReader bufferedreader = new BufferedReader(filereader);
while ((line = bufferedreader.readLine()) != null)
{
num = countWords(line);
System.out.println(num);
}
}
//Always close file
catch(FileNotFoundException ex)
{
System.out.println("Unable to open file '" + fileName + "'");
}
catch(IOException ex)
{
System.out.println("Error reading file '" + fileName + "'");
}
}
}
The source of your problem is up here.
public static int countWords(String str)
{
int count = 1, num_of_letters = 0, final_count=1;
for (int i=0;i<=str.length()-1;i++)
{
//This line
if (str.charAt(i) == ' ' && str.charAt(i+1)!=' ')
Because you let i go all the way to str.length()-1, str.charAt(i+1) will exceed the last index position.
For the word "taken"
str.length() = 5;
Index positions 0-4.
When i is 4, src.charAt(i+1) will go for 5.
I think this will solve it.
if (str.charAt(i) == ' ' && ((i+1) < str.length()) && str.charAt(i+1)!=' ')
You get the exception because of using str.charAt(i+1) != ' '. If i is 0 and length of the string is 1, i + 1 will try to find element at the position 1 which will throw the exception. You may need to add the condition to check if i is less than (the length of the array -1 ) prior to that.

Why do i get a NullPointerException at If statement in do while loop when reading a simple textfile in Java

I'm new in Java, I have a lot of work with text and I've got an idea to make a simple program to do my work. I'm getting error Exception in thread "main" java.lang.NullPointerException at com.text.work.Main.main(Main.java:25)
public class Main {
public static void main(String[] args) throws IOException {
int someNumber = 0;
PrintWriter saveFileOne = new PrintWriter("save.txt");
PrintWriter saveFileTwo = new PrintWriter("otherThings.txt");
FileReader fileReader = new FileReader("read.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String word = bufferedReader.readLine();
do {
word = bufferedReader.readLine();
if (word.toString().equals("true")) { //this is line 25
saveFileOne.println("No: " + ++someNumber + " = " + word);
} else {
saveFileTwo.println("Yes: " + someNumber + " = " + word);
}
} while (word != null);
saveFileOne.close();
saveFileTwo.close();
bufferedReader.close();
System.out.println("Done!");
}
}
From the BufferedReader#readLine() documentation:
Returns: A String containing the contents of the line, not including
any line-termination characters, or null if the end of the stream has
been reached
This means you've obviously reached the end of the stream.
If I were you, I would change the loop with a while one.
while ((word = buffer.readLine()) != null) {
..
}
Obviously word is null because bufferedReader.readLine() encountered the end of the stream and returned null.
You should do the check against null before entering the while body
while(null != (word = bufferedReader.readLine())) {
}
and to avoid such NPEs in general while comparing with constants call equals this way:
"true".equals(other string) // "true" is never null
Make sure that word is not null. Change the code as following code snippet.
do {
word = bufferedReader.readLine();
if(word != null) { //If word is null, no need to go in if block
if (word.toString().equals("true")) {
saveFileOne.println("No: " + ++someNumber + " = " + word);
} else {
saveFileTwo.println("Yes: " + someNumber + " = " + word);
}
}
} while (word != null);
You can also change your loop for reading a file can done easily using following code
if(buffer != null) {
while ((word = buffer.readLine()) != null) {
if (word.toString().equals("true")) {
saveFileOne.println("No: " + ++someNumber + " = " + word);
} else {
saveFileTwo.println("Yes: " + someNumber + " = " + word);
}
}
}
I've the same problem today, two addidional brackets is the answer
(word = bufferedReader.readLine()) != null)

Reading an inputStream all at once [duplicate]

This question already has answers here:
How do I read / convert an InputStream into a String in Java?
(62 answers)
Closed 9 years ago.
I have developed a j2me application that connects to my webhosting server through sockets. I read responses from the server using my own extended lineReader class that extends the basic InputStreamReader. If the server sends 5 lines of replies, the syntax to read the server replies line by line is:
line=input.readLine();
line = line + "\n" + input.readLine();
line = line + "\n" + input.readLine();
line = line + "\n" + input.readLine();
line = line + "\n" + input.readLine();
In this case, i can write this syntax because i know that there is a fixed number of replies. But if I dont know the number of lines, and want to read the whole inputStream at once, how should I modify the current readLine() function. Here's the code for the function:
public String readLine() throws IOException {
StringBuffer sb = new StringBuffer();
int c;
while ((c = read()) > 0 && c != '\n' && c != '\r' && c != -1) {
sb.append((char)c);
}
//By now, buf is empty.
if (c == '\r') {
//Dos, or Mac line ending?
c = super.read();
if (c != '\n' && c != -1) {
//Push it back into the 'buffer'
buf = (char) c;
readAhead = true;
}
}
return sb.toString();
}
What about Apache Commons IOUtils.readLines()?
Get the contents of an InputStream as a list of Strings, one entry per line, using the default character encoding of the platform.
Or if you just want a single string use IOUtiles.toString().
Get the contents of an InputStream as a String using the default character encoding of the platform.
[update] Per the comment about this being avaible on J2ME, I admit I missed that condition however, the IOUtils source is pretty light on dependencies, so perhaps the code could be used directly.
If I understand you correctly, You can use a simple loop:
StringBuffer sb = new StringBuffer();
String s;
while ((s = input.readLine()) != null)
sb.append(s);
Add a counter in your loop, and if your counter = 0, return null:
int counter = 0;
while ((c = read()) > 0 && c != '\n' && c != '\r' && c != -1) {
sb.append((char)c);
counter++;
}
if (counter == 0)
return null;
Specifically for web server !
String temp;
StringBuffer sb = new StringBuffer();
while (!(temp = input.readLine()).equals("")){
sb.append(line);
}

Categories

Resources