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

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]);
}
}

Related

Running multiple replaceAll statements in Java

This is probably a stupidly easy question but it's been a long day.
I'm trying to remove the comments from a java program. To do this i'm trying to use replaceAll, but I'm not sure how to run all 3 of the statements on the file at the same time. Is there a way besides regex that I should be using here? Or is there an easy fix? Here is my code:
import java.io.*;
import java.util.*;
public class Ex13Ch6 {
public static void main(String args[]) throws FileNotFoundException {
File file = new File("killComment.txt");
Scanner s = new Scanner(file);
stripComments(s);
}
public static void stripComments(Scanner s) {
while(s.hasNext()) {
String input = s.nextLine();
String regex = "/*";
// Removes /* from the file
String change = input.replaceAll("/\\*", "");
// Removes */ from the file
String change2 = input.replaceAll("\\*/", "");
// Removes // from the file
String change3 = input.replaceAll("//", "");
System.out.println(change2);
}
}
}
Here is the text file:
// Name: Conner Murowchick
// Email: conner.murowchick#bellevuecollege.edu
// Program description:
/*
Write a method called flipLines that accepts a Scanner for an input
file and writes to the console the same file's contents with each
pair of lines reversed in order. If the file contains an odd number
of lines, leave the last line unmodified.
*/
// importing file and Scanner
import java.io.*;
import java.util.*;
import java.io.FileNotFoundException;
public class Ex7Ch6 {
public static void main(String[] args) throws FileNotFoundException{
// Calling the flipLines method
flipLines();
}
public static void flipLines() throws FileNotFoundException {
// Calls a new file, "jabberwocky.txt"
File file = new File("jabberwocky.txt");
// Scans the file "jabberwocky.txt" and creates a Scanner s to read it.
Scanner s = new Scanner(file);
// creates a new variable "noOfLines" that is an integer equal to 0
int noOfLines = 0;
// A while loop that checks if there is another line to scan.
while(s.hasNextLine()) {
// If there is another line to scan, the scanner goes to the next line
s.nextLine();
// The variable noOfLines increments while this loop runs.
noOfLines++;
}
// Creates a new scanner called s2 that reads the file "jabberwocky.txt"
Scanner s2 = new Scanner(file);
// A for loop that runs when i is less than half of the variable noOflines
for (int i=0; i < (noOfLines / 2); i++) {
// String called line1 that equals scanner s2 reading the next line of text
String line1 = s2.nextLine();
// String called line2 that equals scanner s2 reading the next line of text
String line2 = s2.nextLine();
// Prints the Second line first
System.out.println(line2);
// Prints the First line second
System.out.println(line1);
}
}
}
Your solution cannot work because it's losing the changes everytime.
Try:
// Removes /* from the file
String change = input.replaceAll("/\\*", "");
// Removes */ from the file
String change2 = change.replaceAll("\\*/", "");
// Removes // from the file
String change3 = change2.replaceAll("//", "");
You can even concat in one statement:
String change = input.replaceAll("/\\*", "").replaceAll("\\*/", "").replaceAll("//", "");
Anyway, this won't remove the comments, it will just "uncomment" some comments. As user202729 is suggesting, you need a parser to remove the multi line comments. As for the commented single lines, you need a regular expression more specific, like:
"/^[\s]*[/]+.*/"

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]);

Convert string to doubles in a .txt file?

I have a .txt file of numbers that are formatted like the following:
1.2 2.3 3.4 4.5
2.0 3.0 4.0 5.0
6.0 7.0 8.0 9.0
I'm trying to use a scanner to take each line as a string, convert each number to a double and then add them together to print to a new .txt file.
My error message looks like this:
Exception in thread "main" java.lang.NumberFormatException: For input
string: "1.2 2.3 3.4 4.5" at
sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110) at
java.lang.Double.parseDouble(Double.java:538) at
scanstrings.ScanStrings.parseDouble(ScanStrings.java:51) at
scanstrings.ScanStrings.main(ScanStrings.java:33)
I was trying to use a split to separate each number so that they could be converted to doubles, but no matter what I do nothing seems to work, and I've found ways to split using spaces and periods but each way I try returns the same error message.
My code basically looks like this right now (I'm just starting so I'm sorry if it's just bad, I've also been messing with this for a while so some parts might just not make sense
//Construct Scanner object for the input file
Scanner input = new Scanner (new File("one.txt"));
//Construct Scanner object for the output file
PrintWriter output = new PrintWriter("result.txt");
//Read lines from the input file
while(input.hasNextLine()){
String line = input.nextLine();
String[] conv = line.split("\\s+");
String dub1 = conv[0];
String dub2 = conv[1];
String dub3 = conv[2];
String dub4 = conv[3];
//convert to double
double dub = parseDouble(line);
//compute sum
double total = 0;
if (dub != 0) //protect against division by zero
{
total += dub;
}
System.out.printf("\n", dub, total);
}
input.close();
output.close();
}
public static double parseDouble(String conv) throws NumberFormatException{
int i = 0;
while (!Character.isDigit(conv.charAt(i))) { i++; }
return Double.parseDouble(conv.substring(i).trim());
}
Welcome to StackOverflow!
You've split your line into individual terms, but then are passing the whole line to your parsing with this:
double dub = parseDouble(line);
Instead, try:
double dub = parseDouble(conv[0]);
for the first value. (You may even want to try creating a loop, for all values.)
(as far as i understood you wish to add the numbers in each line from input file, and print it on new line, in output file). An easier way would be to rely on Double.parseDouble(String) to convert the string to Double. New version of your parseDouble(line)
public static double parseDouble(String line){
double res = 0;
for(String number : line.split("\\s+") ){
try{
res += Double.parseDouble(number);
}
catch(NumberFormatException ex){
System.out.println("Cannot convert " + number + " to double");
}
finally{
return res;
}
}
So in that case, you should rename your parseDouble(String line) to getSum(String line)

Cannot print to text file from within while-loop

So I'm at a point in my program where I want to read from a csv file (which has two columns), do some light calculation on the first column (after I check whether or not it has any content), then print the new number (which I calculated from column 1 in the first file) and the contents of the second column from the original file to a new text file.
Without a while loop I have no trouble running calculations on the numbers from the original text file, then printing them to the new file. However ANY printing from inside the while loop is giving me an error. In fact, anything other than reading the file and parsing it into an array of strings is giving me an error from inside the while loop.
These are the top two lines of my stackTrace with the code I currently have posted below:
"Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
at finalProyect.User.makeMealPlan(User.java:476)"
Line 476 being the line in my while loop: "if (array2[0].isEmpty())"
After hours of searching and tinkering I thought it was time to ask for help. Thanks in advance for any help you can provide.
public void makeMealPlan() {
String fileIn = "mealPlan1.csv";
Scanner inputStream = null;
String fileOut = userName + ".txt";
PrintWriter outputStream = null;
try {
inputStream = new Scanner(new File(fileIn));//opens and reads pre-configured meal plan
outputStream = new PrintWriter(fileOut);//creates output file for meal plan
} catch(FileNotFoundException e3) {
fileNotFound();
e3.printStackTrace();
}
outputStream.println(toString());
outputStream.println();
String line0 = inputStream.nextLine();
String[] array0 = line0.split(","); //Splits line into an array of strings
int baseCalories = Integer.parseInt(array0[0]); //converts first item in array to integer
double caloricMultiplier = (caloricNeeds / baseCalories); //calculates the caloricMultiplier of the user
String line1 = inputStream.nextLine();//reads the next line
String[] array1 = line1.split(",");//splits the next line into array of strings
outputStream.printf("%12s %24s", array1[0], array1[1]); //prints the read line as column headers into text file
while(inputStream.hasNextLine()) {
String line = inputStream.nextLine(); //reads next line
String[] array2 = line.split(",");
if(array2[0].isEmpty()) {
outputStream.printf("%12s %24s", array2[0], array2[1]);
} else {
double quantity = Double.parseDouble(array2[0]);
quantity = (quantity * caloricMultiplier);
outputStream.printf("%12s %24s", quantity, array2[1]);
}
}
outputStream.close();
System.out.println(toString());
}
Okay, so there were a few things wrong. However with #NonSecwitter's suggestion I was able to pin it down. So first thing (again as NonSecwitter mentioned) I had empty fields in my .csv which was throwing the ArrayIndexOutOfBounds" error. So what I did was I filled every empty field in my .csv with the string "empty". Once I did that I was able to at least print the next line.
After that, I ran into another error which was that this line:
double quantity = Double.parseDouble(array2[0]);
could not be separated from the the preceding read/split statements by being inside of an if-loop. So I ended up rewriting the guts of the entire while-loop and needed to throw an exception like so:
while (inputStream.hasNextLine())
{
String[] array2 = null;
try
{
String line = inputStream.nextLine(); //reads next line
array2 = line.split(",");
double quantity = Double.parseDouble(array2[0]);
if (!isStringNumeric(array2[0]))
throw new NumberFormatException();
quantity = Math.ceil(quantity * caloricMultiplier);
outputStream.printf("%12.1f %15s\n", quantity, array2[1]);
}
catch(NumberFormatException e1)
{
if (array2[1].equals("empty"))
outputStream.printf("%12s %15s\n", " ", " ");
else
outputStream.printf("%12s %15s\n", " ", array2[1]);
}
}
While my program is now currently working just fine, I'd still really appreciate an explanation as to why I ended up having to throw an exception to get the code to work. Are there certain restrictions with using PrintWriter inside of a while-loop? Also, I very much appreciate everybody's feedback. I think with all the comments/suggestions combined I was able to determine where my problems were (just not WHY they were problems).
Thanks!!!
It would help if you provided sample CSV data and an example of the related output you expect in <userName>.txt.
Short of this I can only help insofar as saying I do not get an exception with your code.
Here is what I got with a quick Java project in Eclipse using project and class-file names gleaned from your exception output (finalProyect and User.java respectively), pasting your code into the class file (User.java), and massaging it a bit for a sanity check...
package finalProyect;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
public class User {
public void makeMealPlan()
{
String fileIn = "C:\\Temp\\mealPlan1.csv";//"mealPlan1.csv"; // FORNOW: adjusted to debug
Scanner inputStream = null;
String userName = "J0e3gan"; // FORNOW: added to debug
String fileOut = "C:\\Temp\\" + userName + ".txt"; // FORNOW: adjusted to debug
PrintWriter outputStream = null;
try
{
inputStream = new Scanner(new File(fileIn));//opens and reads pre-configured meal plan
outputStream = new PrintWriter(fileOut);//creates output file for meal plan
}
catch(FileNotFoundException e3)
{
//fileNotFound(); // FORNOW: commented out to debug
e3.printStackTrace();
}
outputStream.println(toString());
outputStream.println();
String line0 = inputStream.nextLine();
String[] array0 = line0.split(","); //Splits line into an array of strings
int baseCalories = Integer.parseInt(array0[0]); //converts first item in array to integer
int caloricNeeds = 2000; // added to debug
double caloricMultiplier = (caloricNeeds / baseCalories); //calculates the caloricMultiplier of the user
String line1 = inputStream.nextLine();//reads the next line
String[] array1 = line1.split(",");//splits the next line into array of strings
outputStream.printf("%12s %24s", array1[0], array1[1]); //prints the read line as column headers into text file
while (inputStream.hasNextLine())
{
String line = inputStream.nextLine(); //reads next line
String[] array2 = line.split(",");
if (array2[0].isEmpty())
outputStream.printf("%12s %24s", array2[0], array2[1]);
else
{
double quantity = Double.parseDouble(array2[0]);
quantity = (quantity * caloricMultiplier);
outputStream.printf("%12s %24s", quantity, array2[1]);
}
}
outputStream.close();
System.out.println(toString());
}
public static void main(String[] args) {
// FORNOW: to debug
User u = new User();
u.makeMealPlan();
}
}
...and an example of what it output to J0e3gan.txt...
finalProyect.User#68a6a21a
3000 40 2500.0 50 4000.0 25
...with the following (complete-WAG) data in mealPlan1.csv:
2000,20
3000,40
2500,50
4000,25
Comment out the offending code and try to println() array2[0] and see if it gives you anything.
while (inputStream.hasNextLine())
{
String line = inputStream.nextLine(); //reads next line
String[] array2 = line.split(",");
System.out.println(array2[0]);
//if (array2[0].isEmpty())
// outputStream.printf("%12s %24s", array2[0], array2[1]);
//
//else
//{
//
// double quantity = Double.parseDouble(array2[0]);
// quantity = (quantity * caloricMultiplier);
// outputStream.printf("%12s %24s", quantity, array2[1]);
//}
}
or, try to print the length. If the array were empty for some reason array2[0] would be out of bounds
System.out.println(array2.length);
I would also print line to see what it's picking up
System.out.println(line);

While loop trouble for a file reader?

I am creating a program for class that reads in a CSV file and does various mathematical equations on the data given in the file.
The CSV file is in the set up:
longitude1, latitude1, timeStamp1
longitude2, latitude2, timeStamp2
longitude3, latitude3, timeStamp3
(and it continues on for approximately 100 different coordinates).
Right now I am focusing on the longitude values---I am having difficulty getting my while loop to perform the operations i need it too. I need to be able to get the program to subtract longitude2 from longitude1 (where lon1 and lon2 are changing to as we go through the loop...ultimately going through every coordinate).
The problem I am having is that the loop isn't creating an 'overlap' (for lack of better term). It's performing the math on the first two coordinates and then skipping down to the next two... thus skipping every other operation.
[ i.e. : the loop performing: lon2--lon1 and lon4-lon3 but is skipping lon3-lon2 ]
I have a hunch that my problem lies at the start of my while loop but I honestly don't know how to fix it. I would love some help.
Below is the code I have currently:
import java.io.*;
import java.util.*;
public class SearchAndR {
public static void main(String[] args) throws FileNotFoundException {
// creates a Scanner called "keyboard" to read in the file name
Scanner keyboard = new Scanner(System.in);
// prompts user for file name
System.out.println("Enter the name of the file you intend to read in");
// Stores file name as a string so that we may read it in
String file = keyboard.nextLine();
// creates a new Scanner called fr(short for filereader) so we can read
// in the file
// then we create a File object using the constructor new with the class
// "File"
// this takes in our string "file" as a parameter to read it in
// reading in our file object to the scanner
Scanner fr = new Scanner(new File(file));
// Creating format for hike1.csv file
System.out.println("--- Hike Analysis ---");
System.out.println("File: " + file);
// Calling HW4 Class to use in the rest of the program
HW4Util util = new HW4Util();
// Establishing counting variable for distance for the while loop
double totaldistance = 0;
while (fr.hasNextLine()) {
String line = fr.nextLine();
String[] stamp1 = line.split(",");
String line2 = fr.nextLine();
String[] stamp2 = line2.split(",");
double lon1 = Double.parseDouble(stamp1[0]);
double lat1 = Double.parseDouble(stamp1[1]);
String time1 = (stamp1[2]);
double lon2 = Double.parseDouble(stamp2[0]);
double lat2 = Double.parseDouble(stamp2[1]);
String time2 = (stamp2[2]);
// This is just to check to see if the overlap is occurring!
// This should not be included in the project.
System.out.println("this is longitude" +lon1);
System.out.println("this is longitude" +lon2);
// returns the distance between two coordinates as a fraction of a
// mile
double dist = util.distance(lat1, lon1, lat2, lon2);
totaldistance = totaldistance + dist;
totaldistance = (double) (Math.round(totaldistance * 10000)) / 10000;
}
System.out.println("Total distance traveled: " + totaldistance + " miles");
} // end method main
} // end class filereader
Its because you're reading 2 lines in one loop run. I'd suggest do something like this:
String previousLine;
String[] previousStamp;
if (fr.hasNextLine())
{
previousLine = fr.nextLine();
previousStamp = previousLine.split(",");
}
while (fr.hasNextLine()) {
String currentLine = fr.nextLine();
String[] currentStamp = line.split(",");
//do your math here
//...
//swap values
previousStamp = currentStamp;
}
Why its not working as you intended? Well, imagine a pointer thats currently at the beggining of your file.
With fr.nextLine() you are reading line its currently pointed and the pointer goes down.
In one run of your loop you read 2 consecutive lines, do your math and in next run again reading 2 more lines

Categories

Resources