Receiving StringIndexOutOfBoundsException but unable to locate the source - java

My task:
Use scanner method to extract a string, a float, and an int from a line of data.
The data format is:
Random String, 240.5 51603
Another String, 41.6 59087
etc.
My source snippet:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class readTest {
public static void main(String args[]) throws FileNotFoundException
{
System.out.println ("Enter file name");
Scanner scanInput = new Scanner(System.in); //Scanner for reading keyboard input for file name
String fileName = scanInput.nextLine(); //Defines file name as a string from keyboard
File inputTxt = new File(fileName); //Declares the file based on the entered string
Scanner in = new Scanner(inputTxt);
do {
int a; //variable to count how many characters in name
String baseStringA = in.nextLine(); //read whole line as string
a = baseStringA.indexOf(","); //defines a as the posistion of the comma
String reduceStringA = baseStringA.substring(0, a); //reduces string to everything before comma
Scanner scanA = new Scanner(baseStringA).useDelimiter("[^.0-9]+"); //removes letters and comma from string
Float numberA = scanA.nextFloat();
int integerA = scanA.nextInt();
System.out.print (reduceStringA + numberA + integerA);
} while (in.hasNextLine());
}
}
So I finally managed to spit out this code after researching a few different topics (I am pretty new to any type of coding) and I was so excited that I managed to get the output I wanted. But after attempting to implement a loop to make the process repeat for all of the available lines, I frequently hit a wall with the error java.lang.StringIndexOutOfBoundsException after the program prints the output of the first line.
The full error:
String index out of range: -1
at java.lang.String.substring(Unknown Source)
at readTest.main(readTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
I tried to research a little, and I'm convinced it comes from my line
String reduceStringA = baseStringA.substring(0, a);
This seemed more obvious as I tried to read the actual info given by the error, but when I try to trace where the program is having problems I come up empty.
Is anybody able to spot my rookie mistake? Or am I simply going about this process entirely wrong?
The input txt:
Stringy String, 77.2 36229
More Much String, 89.4 24812
Jolly Good String, 182.3 104570
is an example of me getting the error
While the input
Random String, 240.5 51603
Another String, 41.6 59087
String String, 182.6 104570
works as intended
Which is really strange to me.

int a; //variable to count how many characters in farm name
String baseStringA = in.nextLine(); //read whole line as string
a = baseStringA.indexOf(","); //defines a as the posistion of the comma
String reduceStringA = baseStringA.substring(0, a);
If there is no comma in the baseStringA baseStringA.indexOf() will return -1. Thus then you will try to get sub string (0,-1) and thus the error.
Finally the error comes from here baseStringA.substring(0, a); because one of begin index 0 is larger than the end index a (which is -1) - more here

Related

"java.lang.NumberFormatException: empty String" with a not empty String

I am currently working on a personal project outside of class and am running into some issues while reading in a text file into a linked list. When reading in the first double I get a
java.lang.NumberFormatException: empty String
error. I added a print line into the program to print out what I am trying to parse into a double and the variable is in fact, not empty, and is in fact a double.
Like I said above, I added a print line to print out the string I am trying to parse into a double and it seems to be okay. Here is the String that is read in and split into the array I am printing from:
500.0 % 04/05/2019 % This is paycheck 1 % true % 49.5
I have to parse two strings into doubles and I only run into problems with the first one. When I comment out the first double being parsed, the program runs with no problems. Here is the full output from running to program
*File loading*
*500.0*
*Exception in thread "main" java.lang.NumberFormatException: empty String*
*at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)*
*at sun.misc.FloatingDecimal.parseDouble(Unknown Source)*
*at java.lang.Double.parseDouble(Unknown Source)*
*at fileHandling.readPaycheck(fileHandling.java:194)*
*at UserMenu.main(UserMenu.java:20)*
The problems happens in the "Splitting the array into its appropriate temp variables" section in this line of code:
payCheckAmount = Double.parseDouble(tempArray[0]);
Here is the code for the method this is in
public void readPaycheck(LinkedList<PayCheck> paycheck) throws IOException {
// Declare Variables
Scanner sc = new Scanner(payChecks); // Scanner used to read in from the payChecks text file
String temp; // A string used to hold the data read in from the file temporarily
String[] tempArray; // A String array used to temporarily hold data from the text file
double payCheckAmount; // A double holding the amount of the paycheck
String paycheckDate; // A string holding the date of the paycheck
String description; // A string holding a description of the paycheck
boolean payCheckSplit; // A boolean stating if the paycheck has been split or not
double amountUnSplit; // A double
// A while loop that runs while the text file still has data in it
while (sc.hasNextLine()) {
// Reading in a new line from the paycheck file
temp = sc.nextLine();
// Splitting the line into an array
tempArray = temp.split(" % ");
// Temp output used for testing of the issue at hand
System.out.println(tempArray[0]);
// Splitting the array into its appropriate temp variables
payCheckAmount = Double.parseDouble(tempArray[0]);
paycheckDate = tempArray[1];
description = tempArray[2];
payCheckSplit = Boolean.parseBoolean(tempArray[3]);
amountUnSplit = Double.parseDouble(tempArray[4]);
// putting the temp variables into a temp paycheck object
PayCheck tempCheck = new PayCheck(payCheckAmount, paycheckDate, description, payCheckSplit, amountUnSplit);
paycheck.add(tempCheck);
}
}
Edit:
Here is a Minimal, Complete, and Verifiable example of the problem I am running into:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class test {
public static void main(String[] args) throws IOException {
// Declare Variables
File payChecks = new File("C:\\Users\\zwtw\\Documents\\paychecks.txt");
Scanner sc = new Scanner(payChecks);
while (sc.hasNextLine()) {
String temp = sc.nextLine();
String[] tempArray = temp.split(" % ");
System.out.println(tempArray[0]);
// Splitting the array into its appropriate temp variables
double payCheckAmount = Double.parseDouble(tempArray[0]);
String paycheckDate = tempArray[1];
String description = tempArray[2];
boolean payCheckSplit = Boolean.parseBoolean(tempArray[3]);
double amountUnSplit = Double.parseDouble(tempArray[4]);
}
}
}
Here is the content of the text file mentioned in the code above:
500.0 % 04/05/2019 % This is paycheck 1 % true % 49.5
450.0 % 04/09/2019 % This is paycheck 2 % true % 49.75
Your text file likely contains empty lines. You can either remove the new lines in the text file, change how the text file is created, or just skip the empty lines when you read it.
This is how you skip the empty lines:
while (sc.hasNextLine()) {
String temp = sc.nextLine();
if (temp.equals("")) { continue; } // <--- notice this line
String[] tempArray = temp.split(" % ");
System.out.println(tempArray[0]);
// Splitting the array into its appropriate temp variables
double payCheckAmount = Double.parseDouble(tempArray[0]);
String paycheckDate = tempArray[1];
String description = tempArray[2];
boolean payCheckSplit = Boolean.parseBoolean(tempArray[3]);
double amountUnSplit = Double.parseDouble(tempArray[4]);
}
}

Constructing an object using a given file

I'm trying to use a constructor to create an object from a file, the file should contain (on the first line) an Int in String format which is meant to be the number of rows for the MD Array and then has a space followed by another Int in String format. I'm trying to "grab" these two Strings, parse them into an int and then instantiate the MD Array by using these two ints I've "grabbed." I'm just not quite sure where I'm going wrong, as I've just begun using File I/O in my coding. Here's my code.
public SeatingChart(File file) throws FileNotFoundException, DataFormatException, IOException
{
Scanner scan = new Scanner(file);
int rows = 0;
int columns = 0;
String rowStr = "";
String colStr = "";
if (scan.hasNext())
{
rowStr = scan.next();
colStr = scan.next();
}
rows = Integer.parseInt(rowStr);
columns = Integer.parseInt(colStr);
seats = new Student[rows][columns];
scan.close();
}
Any help would be much appreciated :)
From your question, You want to grab two numbers, in string format, separated by a space.
I would grab the entire line then trim the string which ensures there is no space before or after the numbers I need. Then split them based on space.
Look at this simplified step by step example. This example will create a file called numbers.txt then put in it string "5 2". Then the file will be read and taken apart to get the numbers.
import java.util.*;
import java.io.*;
import java.nio.*;
PrintWriter fileWriter = new PrintWriter("numbers.txt", "UTF-8");
fileWriter.println("5 2");
fileWriter.close();
File file = new File("numbers.txt");
Scanner input = new Scanner(file);
String numbersString;
if (input.hasNextLine()) numbersString = input.nextLine();
// Trim the string to ensure you have what you need.
numbersString = numbersString.trim();
// Split both numbers according to the space within them.
String[] numsArray = numbersString.split("\\s+");
// Get your numbers.
int row = Integer.valueOf(numsArray[0]);
int col = Integer.valueOf(numsArray[1]);

Read from 1 file to produce 2 files

I've been trying to do this problem for my schoolwork and for the life of me I cannot figure it out.
The problem is: Write a program that reads in "worked_example_1/babynames.txt" and produces two files, boynames.txt and girlnames.txt, separating the data for the boys and girls.
This is the code from Worked Example 11 from wiley.com/go/javaexamples for this problem:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class BabyNames
{
public static final double LIMIT = 50;
public static void main(String[] args) throws FileNotFoundException
{
Scanner in = new Scanner(new File("babynames.txt"));
RecordReader boys = new RecordReader(LIMIT);
RecordReader girls = new RecordReader(LIMIT);
while (boys.hasMore() || girls.hasMore())
{
int rank = in.nextInt();
System.out.print(rank + " ");
boys.process(in);
girls.process(in);
System.out.println();
}
in.close();
}
}
And this:
import java.util.Scanner;
public class RecordReader
{
private double total;
private double limit;
public RecordReader(double aLimit)
{
total = 0;
limit = aLimit;
}
public void process(Scanner in)
{
String name = in.next();
int count = in.nextInt();
double percent = in.nextDouble();
if (total < limit)
{
System.out.print(name + " ");
}
total = total + percent;
}
public boolean hasMore()
{
return total < limit;
}
}
I created the babynames.txt and put in the same src folder as the .java file, it comes up with file not found, if I give the direct path to the file with
Scanner in = new Scanner(new File("C:/Users/me/SkyDrive/Schoolwork/CIS150AB/Chapter 11.1/src/babynames.txt"));
it finds the file but gives me this error:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at BabyNames.main(BabyNames.java:20)
To me it looks like this error is because of Line 20 where int rank = in.nextInt(); and its looking for a string when its looking for an int, but this is directly from Wiley website so I am not sure.
Any help with this would be appreciated, apparently I am not meant for online classes for Java. Next class I am taking in school once there is one that works around my schedule.
If this is the format of your babynames.txt, this is what'll happen (I think, didn't try it).
The scanner "in" reads the first int into "rank" (OK)
Enter into boys.process()
"in" reads the first name (Jacob)
"in" tries to read the first int (1), but finds 1.0013, which is not an int
This scenario doesn't match your error (you'd get a stacktrace from RecordReader rather than from BabyNames) but maybe the line of thinking will work for you.
Try it with a debugger. If you can't, use in.next() rather than in.nextInt() or in.nextDouble(). You can than print the value and see why it's not what you think it is.
Your question actually raises two questions. The answer to the hidden one may be:
try (InputStream inputStream = BabyNames.class.getResourceAsStream("/babynames.txt");
Scanner in = new Scanner(inputStream))
{
// do stuff with in
}

Importing Text Files to be read using Scanner

private void readWords() throws IOException {
initialCt = readFrom("C:\\Curses1.txt", initialWords);
midCt = readFrom("C:\\Curses2.txt", middleWords);
endCt = readFrom("C:\\Curses3.txt", endingWords);
} // readWords()
// Pre: fileName is the name of an input file. Tokens (items) in the
// file are strings separated by whitespace.
// Pre: wordList has been allocated and is large enough to hold all
// the tokens in the input file.
// Post: wordList contains all the tokens in the input file, one token
// per string.
private int readFrom(String fileName, String[] wordList) throws IOException {
int count= 0;
FileInputStream fstream = new FileInputStream(fileName);
Scanner scan2 = new Scanner (fstream);
while (scan2.hasNext()){
initialWords[count] =scan2.nextLine();
middleWords[count] = scan2.nextLine();
endingWords [count] = scan2.nextLine();
String words = scan2.next();
++count;
}
return count;
} // readFrom()
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at Curses.readFrom(Curses.java:95)
at Curses.readWords(Curses.java:63)
at Curses.run(Curses.java:51)
at Curses.main(Curses.java:131)
I am trying to read in three different text files and store their values in three different arrays but java cannot find the file. This is only part of the class but this is where the error is occurring. Any help would be greatly appreciated!
i believe it is happening because of the String words = scan2.next();
if the file doesn't have the 4th line then this exception would be thrown. that is the only possible way i can think of. check the files if there is a 4th line.

Comparing user input string to string read from text file

I'm currently writing this program that I require to read info from a text file and to then compare the info read to a user input and output a message saying if it was a match or not.
Currently have this. The program is sucessfully reading the data specified but I can't seem to compare the strings correctly at the end and print a result.
Code is below any help would be greatly appreciated.
import java.util.Scanner; // Required for the scanner
import java.io.File; // Needed for File and IOException
import java.io.FileNotFoundException; //Required for exception throw
// add more imports as needed
/**
* A starter to the country data problem.
*
* #author phi
* #version starter
*/
public class Capitals
{
public static void main(String[] args) throws FileNotFoundException // Throws Clause Added
{
// ask the user for the search string
Scanner keyboard = new Scanner(System.in);
System.out.print("Please enter part of the country name: ");
String searchString = keyboard.next().toLowerCase();
// open the data file
File file = new File("CountryData.csv");
// create a scanner from the file
Scanner inputFile = new Scanner (file);
// set up the scanner to use "," as the delimiter
inputFile.useDelimiter("[\\r,]");
// While there is another line to read.
while(inputFile.hasNext())
{
// read the 3 parts of the line
String country = inputFile.next(); //Read country
String capital = inputFile.next(); //Read capital
String population = inputFile.next(); //Read Population
//Check if user input is a match and if true print out info.
if(searchString.equals(country))
{
System.out.println("Yay!");
}
else
{
System.out.println("Fail!");
}
}
// be polite and close the file
inputFile.close();
}
}
You should try reading the input from a textField in an user interface(visible window) where the user puts the country and getting that as raw input shortens the code.(Only if you have a visible window on screen)
I don't have that good experience with scanners, because they tend to crash my applications when I use them. But my code for the same test does only include a scanner for the file which does not crash my application and looks like following:
Scanner inputFile = new Scanner(new File(file));
inputFile.useDelimiter("[\\r,]");
while (inputFile.hasNext()) {
String unknown = inputFile.next();
if (search.equals(unknown)) {
System.out.println("Yay!");
}
}
inputFile.close();
I think the easiest way to compare string against a file is to add a visible window where the user types the country, and reading the input to a string with String str = textField.getText();
I am guessing that your comparison is failing due to case-sensitivity.
Should your string comparison not be CASE-INSENSITIVE?
There are a few possible issues here. First, you're converting the searchString to lower case. Are the data in the CSV also lower case? If not, try using equalsIgnoreCase instead. Also, it seems to me like you should be able to match parts of the country name. In that case, equals (or equalsIgnoreCase) would only work if the user inputs the complete country name. If you want to be able to match only a part, use contains instead.

Categories

Resources