First and last name buffered reader giving me troubles - java

I've fixed many other issues but after fixing one that I thought was the last error, I came a Null pointer exception.
package com.Text.Scanner.java;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class TextScanner {
public static void main(String ...args) throws IOException{
Scanner sc = new Scanner(System.in);
System.out.println("Enter names for parsing");
String input = sc.nextLine();
ArrayList<String> names = new ArrayList<String>();
for (int i = 0;i<=input.length();i++) {
names.add(input.substring(0, input.indexOf(",")));
input = input.substring(input.indexOf(",")+1);
}
System.out.println(names);
// handles the string import to arraylist
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader("sample.txt"));
//finds file
String line = reader.readLine();
//reads line
while (line != null) {
for (int i = 0; i <= line.length(); i++) {
if (line.contains(names.get(i))) {
//gets name from array to scan line for
System.out.println(line.substring(4, line.indexOf(names.get(i)) + names.get(i).length()));
//controls length
line = reader.readLine();
}
}
}
reader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
The goal here is to scan each line for a name (first and last) then print the number aside their name on the text file.
first line: 1234 Billy Smith
second line: 5678 John Smith
what you input: Billy Smith,John Smith,
The point of it is to scan the file for the list of first and last names in an arraylist and then output the numbers and name. The program works if I go in order in the whole list, but if I don't then it gives me this. I have tried to put reader.reset() if the if statement finds a match and then if it doesn't it reads another line, but that doesn't work
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 3 out of bounds for length 3
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:373)
at java.base/java.util.ArrayList.get(ArrayList.java:426)
at com.Text.Scanner.java.TextScanner.main(TextScanner.java:32)

for (int i = 0; i <= line.length(); i++) {
if (line.contains(names.get(i))) {
So basically i goes from O to line.length() (number of char in the line) and you use it to accces your names with name.get(i) that absolutely no reason to be the same size (it is more the number of lines on the first line)
But why don't you debug your code ? The error you got says the error is in TestScanner line 32 calling the method get. It already say where the error !
You could even rerun that program with the debugger, and ask it to stop when an exception is raised so it would stop exactly at the right place and you be able to look at the various variables.

Related

Need help fixing NumberFormatException error [duplicate]

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 1 year ago.
I'm trying to read in a text file which looks similar to this:
0000000000
0000100000
0001001000
0000100000
0000000000
Here is my code:
public static int[][] readBoard(String fileName) throws FileNotFoundException {
File life = new File(fileName);
Scanner s = new Scanner(life);
int row = s.nextInt();
int columns = s.nextInt();
int [][] size = new int [row][columns];
for (int i=0; i <= row; i++) {
String [] state = new String [columns];
String line = s.nextLine();
state = line.split("");
for (int j=0; i <= columns; i++) {
size[i][j] = Integer.parseInt(state[j]);
}
}
return size;
}
It keeps giving me this error. I think it's the Integer.parseInt(state[j]) that is giving me trouble, but I don't know why.
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:662)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at Project5.readBoard(Project5.java:33)
at Project5.main(Project5.java:9)
I've executed your code with the example input, and you have logical issues in the code. With the exmaple input the code doesn't even reach the parseInt() line where the asked NumberFormatException could be thwrown. I assume you have tried your code in a different input. The Exception message is staithforward, you tried to parse an empty string to number. It's a typical NumberFormatException. The parseInt() function can throw Exception, so your code must be prepared for it.
The other problem is a basic logical issue in your algorithm. Your row and column variables will be populated with the first to integer token from the text. Based on the exampe input the first integer token will be the first row 0000000000 which integer value is 0, and the second token is 0000100000 which will parsed as 100000. So you are trying to initialize an array with these dimensions which is imposible.
To calculate the row count, you have to read the file line by line. And to get the column counts you have the check the length of the lines. (It can open a new question, how do you want to handle the not properly formatted input file, because in the file the line length can be various.)
That means you can only be sure with the dimensions of the board if you have already iterated though the file content. To prevent the multiple iteration you should use dinamic collection instead of a standard array, like ArrayList.
That means while you are read the file line by line, you can process the the characters one after another in a line. In this step you should be concidered about the invalid characters and the potential empty characters in the end of the file. And during this iteration the final collection can be built.
This example shows a potention solution:
private static int processCharacter(char c) {
try {
return Integer.parseInt((Character.toString(c)));
} catch (NumberFormatException e) {
return 0;
}
}
public static List<List<Integer>> readBoard(String fileName) throws FileNotFoundException {
List<List<Integer>> board = new ArrayList<>();
File file = new File(fileName);
FileReader fr = new FileReader(file);
try (BufferedReader br = new BufferedReader(fr)) {
String line;
while ((line = br.readLine()) != null) {
line = line.trim(); // removes empty character from the line
List<Integer> lineList = new ArrayList<>();
if(line.length() > 0) {
for (int i = 0; i < line.length(); i++) {
lineList.add(Main.processCharacter(line.charAt(i)));
}
board.add(lineList);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return board;
}

Reading text files in Java and using data

I am required to evaluate the contents of a .txt file, the file includes 5 numbers, all spaced apart by one (ex: 5555 55 45 47 85) on one line.
The problem isn't reading the file, but actually using each number in the file.
Question: How can I grab the 5 numbers and store each into a unique variable?
Code so far:
import java.io.FileReader;
import java.io.BufferedReader;
public class PassFail {
public static void main(String[] args) {
try{
FileReader file = new FileReader("C:\\new_java\\Final_Project\\src\\student.txt");
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
reader.close();
System.out.println(line);
} catch(Exception e) {System.out.println("Error:"+ e);}
}
}
You need to read the file line by line, which you already did. Then you can split the string on space character and iterate over the fields and parse them to Integer
s= reader.readline()
String tokens[]= s.split(" ");
int nums[] = new int[tokens.length];
for(int i=0; i<tokens.lenght; i++) {
nums[i] = Integer.parseInt(tokens[i]);
}
Hope this helps.

NullPointerException error in search through array

I'm trying to run this code. It reads the file successfully, but breaks at the word search itself.
The error:
Exception in thread "main" java.lang.NullPointerException
at WordSearch.main(WordSearch.java:30)
Here's the code:
import javax.swing.JOptionPane;
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class WordSearch{
public static void main(String[] args) throws FileNotFoundException{
String searchWord, fileName; int i=0, j=0;
fileName = JOptionPane.showInputDialog(null, "Please enter the name of the file to be processes: ");
File textFile = new File(fileName);
Scanner scanner = new Scanner(textFile);
String[] file = new String[500];
String[] found = new String[500];
while(scanner.hasNextLine()){
file[i]=scanner.next();
i++;
}
file[i+1]="EoA"; i=0;
searchWord = JOptionPane.showInputDialog(null, "Please input the string to search for: ");
while(!file[i].equals("EoA")){
if (file[i].equals(searchWord)){
if(i==0){
found[j]=file[i]+file[i+1]+"\n";
}
else if(i==500){
found[j]=file[i-1]+file[i]+"\n";
}
else {
found[j]=file[i-1]+file[i]+file[i+1]+"\n";
}
j++;
}
i++;
}
JOptionPane.showMessageDialog(null, found);
}
}
Change
file[i+1]="EoA";
to
file[i]="EoA";
Otherwise, you'll have a null entry in the position that precedes the "EoA" entry, which causes the NullPointerException.
Of course, you can get rid of the "EoA" entry, and just change the loop's condition to :
while (file[i] != null)
That's much more readable.
One last thing, how do you guarantee that your input won't be larger than the 500 length of your array?
This is happening because of your i++ expression. In each iteration i is being incremented and the result gets stored in previous index pointed by the value of i
Possible solution is to use i-1 in the while loop.

Reading data from a table & parsing it

My code is designed to read the contents of a text file and check if the contents are entered in a format that is as follows:
john : martin : 2 : 1
and if that format is followed then it will output it in the format:
john [2] | martin [1]
or else it will be counted as an invalid result and the total numbers will not be added to it whereas if the results are in the format then they will get added to the total so with the example it would display the number of vaild results as 1, invalid as 0 and total number as 3.
My question is that my code doesn't work properly as I get this error:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at reader.main(reader.java:33)
So how would I go about fixing this and reading and displaying the data in thee way that I want? Thanks in advance.
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Locale;
import java.util.Scanner;
public class reader {
/**
* #param args
* #throws FileNotFoundException
* #throws FileNotFoundException
* #throws FileNotFoundException when the file cannot be loaded
*/
public static void main(String[] args) throws FileNotFoundException {
String hteam;
String ateam;
int hscore;
int ascore;
Scanner s = new Scanner(new BufferedReader(new FileReader("results2.txt"))).useDelimiter(":");
// create a scanner which scans from a file and splits at each colon
while ( s.hasNext() ) {
hteam = s.next(); // read the home team from the file
ateam = s.next(); // read the away team from the file
hscore = s.nextInt(); //read the home team score from the file
ascore = s.nextInt(); //read the away team score from the file
System.out.print(hteam); // output the line of text to the console
System.out.print(hscore);
System.out.print(ateam);
System.out.println(ascore);
}
System.out.println("\nEOF"); // Output and End Of File message.
}
}
You're looking for s.next() instead of s.nextLine().
hteam = s.nextLine() reads the entire line "john : martin : 2 : 1", leaving nothing left for ateam.
Edit:
As you've said this still isn't working, I'd guess that you have an extra newline at the end of your input file, which is causing s.hasNext() to evaluate to true. This would cause the Scanner to trip up when it's getting the next input line.
Try Scanner s = new Scanner(System.in).useDelimiter("\\s*:\\s*|\\s*\\n\\s*"); to read multiple lines.
See implementation: http://ideone.com/yfiR2S
To verify that a line is in the correct format, I'd (with inspiration from osoblanco's answer) check that there are 4 words and that the last two are integers:
public static boolean verifyFormat(String[] words) {
// see endnote for isInteger()
return words.length == 4 && /*isInteger(words[2]) && isInteger(words[3])*/;
}
public static void main(String[] args) throws FileNotFoundException {
String hteam;
String ateam;
int hscore;
int ascore;
Scanner s = new Scanner(new BufferedReader(
new FileReader("results2.txt"))).useDelimiter("\\s*:\\s*|\\s*\\n\\s*");
while (s.hasNext()) {
String line = s.nextLine();
String[] words = line.split("\\s*:\\s*");
if(verifyFormat(words)) {
hteam = words[0]; // read the home team
ateam = words[1]; // read the away team
hscore = Integer.parseInt(words[2]); //read the home team score
ascore = Integer.parseInt(words[3]); //read the away team score
System.out.print(hteam); // output the line of text to the console
System.out.print(hscore);
System.out.print(ateam);
System.out.println(ascore);
}
}
System.out.println("EOF");
}
isInteger() can be found here.
I think scanning isn't quite what you want here. I would just use a BufferedReader and do ReadLine to handle 1 line each time through the for loop.
Then verify each line by the following:
1) String.split(":") and verify 4 pieces.
String [] linePieces = nextLine.split(":");
if(linePieces.length!=4)
{
//mark invalid, continue loop
}
2) Trim each piece
for(int i =0; i<4; i++)
linePieces[i] = linePieces[i].trim();
3) Verify piece 3 and piece 4 are numbers, Integer.parseInt with try/catch. In the catch block, count that the line is invalid.
try
{
name1=linePieces[0];
name2=linePieces[1];
score1=Integer.parseInt(linePieces[2]);
score2=Integer.parseInt(linePieces[3]);
//count as success and do logic
}catch(NumberFormatException e){
//invalid line
}

Error using Substring : String Index out of range : -1 *Java*

In this program I am just getting input from a file and trying to get the boys name and the girls name out of it, and also put them in separate files. I have done everything just as the book has stated. And I've also searched everywhere online for help with this but cant seem to find anyone with the same problem. Ive seen problems where its not -1 but a positive number because they went to far out of the string calling a substring over the strings length. But cant seem to figure out this giving me -1 since i's value is 1.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.ArrayList;
public class Homework_11_1 {
public static void main(String[] args)throws FileNotFoundException
{
File inputFile = new File("babynames.txt");
Scanner in = new Scanner(inputFile);
PrintWriter outBoys = new PrintWriter("boys.txt");
PrintWriter outGirls = new PrintWriter("girls.txt");
while (in.hasNextLine()){
String line = in.nextLine();
int i = 0;
int b = 0;
int g = 0;
while(!Character.isWhitespace(line.charAt(i))){ i++; }
while(Character.isLetter(line.charAt(b))){ b++; }
while(Character.isLetter(line.charAt(g))){ g++; }
String rank = line.substring(i);
String boysNames = line.substring(i, b);
String girlsNames = line.substring(b, g);
outBoys.println(boysNames);
outGirls.println(girlsNames);
}
in.close();
outBoys.close();
outGirls.close();
System.out.println("Done");
}
}
Here is the txt file
1 Jacob Sophia
2 Mason Emma
3 Ethan Isabella
4 Noah Olivia
5 William Ava
6 Liam Emily
7 Jayden Abigail
8 Michael Mia
9 Alexander Madison
10 Aiden Elizabeth
I would have written it an other way, using split.
public static void main(String[] args)throws FileNotFoundException
{
File inputFile = new File("babynames.txt");
Scanner in = new Scanner(inputFile);
PrintWriter outBoys = new PrintWriter("boys.txt");
PrintWriter outGirls = new PrintWriter("girls.txt");
while (in.hasNextLine()){
String line = in.nextLine();
String[] names = line.split(" "); // wile give you [nbr][boyName][GirlName]
String boysNames = names[1];
String girlsNames = names[2];
outBoys.println(boysNames);
outGirls.println(girlsNames);
}
in.close();
outBoys.close();
outGirls.close();
System.out.println("Done");
}
Rather than fuss with loops and substring(), I'd just use String.split(" "). Of course, the assignment may not permit you to do this.
But anyway, without giving you the answer to the assignment, I can tell you that your logic is wrong. Walk through it and find out why. If you try running this code on just the first line of the input file, you'll get these values: i=1, b=0, and g=0. Calling line.substring(1,0) is obviously not going to work.

Categories