Error using Substring : String Index out of range : -1 *Java* - 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.

Related

First and last name buffered reader giving me troubles

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.

How to getMethods into a class while Reading a File using arrays?

I have two classes, one with instance variables and the other will read a file. The file with one main loop will store an array of workers. I don't know when the getMethods should be placed.
the file has looks a bit like this:
Joames peter 5 15.00
Laura Kelly 30 12.00
Tim McAdam 18 15.00
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class PayRoll {
private static Scanner kbd;
public static void main(String[] args) {
final int NUMBER_OF_WORKERS = 15;
final String INPUT_FILE = "data.txt";
Worker[] worker_ar = new Worker[NUMBER_OF_WORKERS];
try{
kbd = new Scanner(new File(INPUT_FILE));
}
catch(FileNotFoundException e){
System.err.println("File Not Found!");
}
String line = null;
int i = 0 ;
while((kbd.hasNextLine()) && (i < worker_ar.length))
{
// these are the variables I have in the other class. I need these so I can
// later reverse the file data and comute total pay and average pay.
line = kbd.nextLine();
worker_ar[i] = (getfName(), getlName(), getHours(), gethrly_pay());
i++;
}
kbd.close();
}
// I will put two methods here to make the file reverse
}
Use StringTokenizer with space separator.
Nitpick: Use Employee instead of Worker. It's has more sense, and Worker used in Java for something else.

Searching a list of names in a text file from user input

I'm currently in an Introductory Java class at University and I'm having a bit of trouble. Last semester we started with Python and I became very acquainted with it and I would say I am proficient now in writing Python; yet Java is another story. Things are alot different. Anyway, Here is my current assignment: I need to write a class to search through a text document (passed as an argument) for a name that is inputted by the user and output whether or not the name is in the list. The first line of the text document is the amount of names in the list.
The text document:
14
Christian
Vincent
Joseph
Usman
Andrew
James
Ali
Narain
Chengjun
Marvin
Frank
Jason
Reza
David
And my code:
import java.util.*;
import java.io.*;
public class DbLookup{
public static void main(String[]args) throws IOException{
File inputDataFile = new File(args[0]);
Scanner stdin = new Scanner(System.in);
Scanner inFile = new Scanner(inputDataFile);
int length = inFile.nextInt();
String names[] = new String[length];
for(int i=0;i<length;i++){
names[i] = inFile.nextLine();
}
System.out.println("Please enter a name that you would like to search for: ");
while(stdin.hasNext()){
System.out.println("Please enter a name that you would like to search for: ");
String input = stdin.next();
for(int i = 0;i<length;i++){
if(input.equalsIgnoreCase(names[i])){
System.out.println("We found "+names[i]+" in our database!");
break;
}else{
continue;
}
}
}
}
}
I am just not getting the output I am expecting and I cannot figure out why.
Try this
You should trim() your values as they have extra spaces
if(input.trim().equalsIgnoreCase(names[i].trim()))
I have run your example it runs perfectly after using trim(), you have missed to trim()
Create a seperate scanner class to read line by line.You can use BufferedReader also.
final Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
final String str= scanner.nextLine();
if(str.contains(name)) {
// Found the input word
System.out.println("I found " +name+ " in file " +file.getName());
break;
}
}
If you use Java 8:
String[] names;
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
names = stream.skip(1).toArray(size -> new String[size]);
} catch (IOException e) {
e.printStackTrace();
}

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
}

regext copying second, third and fourth word

I am trying to get the 2nd, 3rd, and 4th word from a file into another file, so far I know how to read a file and I have been trying different things but I don't get it right the code to get the words. This program will read the file.
import java.util.Scanner;
import java.io.File;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
class PrintLines{
public static void main(String[] args) throws FileNotFoundException {
Scanner me = new Scanner(System.in);
System.out.print("File Name: ");
String s = me.next();
File inFile = new File(s);
Scanner in = new Scanner(inFile);
while(in.hasNextLine()){
String line = in.nextLine();
System.out.print(line + "\n");
}
in.close();
}
}
I have tried:
int i=0;
while(!Character.isDigit(in.charAt(i))){
i++;
}
to skip the first numbers, and then get the next three words, but I don't get it right:
986 Nasir 829 0.0040 Janine 1352 0.0069
I would appreciate any advice. Thank you
You can use String.split method
String[] split = line.split(" "); // split by space
System.out.println(split[1] + split[2] + split[3]); // watch out for the array's bounds

Categories