Having an issue reading in a CSV File for a project - java

Hi I'm getting a NumberFormatException error for reading in this CSV text file for a project. Here's the CSV
12345,Left-Handed Bacon Stretcher,125.95,PGH,2
24680,Smoke Shifter,0.98,PGH,48
86420,Pre-dug Post Hole,2.49,ATL,34
25632,Acme Widget,98.29,LOU,342
97531,Anti-Gravity Turbine,895.29,ATL,3
24680,Battery-Powered Battery Charger,252.98,ATL,2
12345,Left-Handed Bacon Stretcher,125.95,LOU,35
97531,Anti-Gravity Turbine,895.29,PHL,8
00000,Glass Hammer,105.90,PGH,8
01020,Inflatable Dartboard,32.95,PGH,453
86420,Pre-dug Post Hole,2.49,LOU,68
86420,Pre-dug Post Hole,2.49,PGH,124
24680,Battery-Powered Battery Charger,252.98,PHL,5
I have a general understanding what is going on. The error is appearing I believe because it reaches the end of the first line and then the error pops up
Exception in thread "main" java.lang.NumberFormatException: For input
string: "2 24680"
This is what I have so far:
import java.io.*;
import java.util.*;
public class Prog7
{
public static void main(String[] args)
{
String warehouseID = null;
String city = null;
String state = null;
int partNumber = 0;
String description = null;
double price = 0.0;
int quantity = 0;
int count = 0;
int numWarehouse = 4;
int numParts = 13;
Scanner warehouseFile = null;
Scanner partFile = null;
Warehouse[] warehouse = new Warehouse[10];
Part[] parts = new Part[20];
try
{
warehouseFile = new Scanner(new File("warehouse.txt"));
while (warehouseFile.hasNext())
{
warehouseID = warehouseFile.next();
city = warehouseFile.next();
state = warehouseFile.next();
warehouse[count] = new Warehouse(warehouseID, city, state);
count++;
}
partFile = new Scanner(new File("parts.txt"));
partFile.useDelimiter(",");
while (partFile.hasNext())
{
partNumber = Integer.parseInt(partFile.next());
description = partFile.next();
price = Double.parseDouble(partFile.next());
warehouseID = partFile.next();
quantity = Integer.parseInt(partFile.next());
parts[count] = new Part(partNumber, description, price, warehouseID, quantity);
count++;
}
}
catch (FileNotFoundException e)
{
System.err.print("warehouse.txt or parts.txt not found");
}
for (int i = 0; i < numWarehouse; i++)
{
System.out.printf("%5s %5s %5s\n", warehouse[i].getWarehouseID(), warehouse[i].getCity(),
warehouse[i].getState());
for (int j = 0; j < numParts; j++)
{
if (parts[j].getWarehouseID().equals(warehouse[i].getWarehouseID()))
{
System.out.printf("%5s %5s %10.2f %5\nd", parts[j].getPartNumber(), parts[j].getDescription(),
parts[j].getPrice(), parts[j].getQuantity());
}
}
}
}
}
I think it has something to do with the program is reading in each value but then there's nothing for going to the next line. I have a tried a partFile.nextLine() instruction and a hasNextLine() while loop and I still get the same error. Is there something perhaps I could do with a newline character?

I think the problem is here:
partFile.useDelimiter(",");
You are telling the scanner to split only on commas. Once it reaches the last item in the first line of parts.txt, it reads onwards until it finds the first comma in the next line, and hence returns 2 followed by an end-of-line followed by 24680 as the next item.
You don't just want to split by commas, you also want to split by newline characters as well. useDelimiter takes a regular expression: the following tells the scanner to split on either a comma or any combination of newline characters:
partFile.useDelimiter(",|[\\r\\n]+");

In addition to Luke Woodward's answer, perhaps you should take into account that the year is 2018, not 1999. The following code should do what you're looking for, with the knowledge of how to parse a line moved into the class where it belongs. I made it a constructor, but it could also be a static valueOf method.
Path warehouseFile = Paths.get("warehouse.txt");
Files.lines(warehouseFile)
.map(Warehouse::new)
.collect(toList());
static class Warehouse {
public Warehouse(String line) {...}
}

Related

Just need a little help debugging my code

I have 3 files, "MyFile" , "myOtherFile" , "yetAnotherFile" that my code will be drawing words from to put them in an array, check to see if they start with an uppercase, and if they do, it will also sort them alphabetically.
all 3 have 3 or more words, one has only one word that starts with a lowercase so I can test that invalid input print line
I am somehow getting all 3 to print the invalid line
Added a counter so if counter > 0 it then does the print statement
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.*;
public class StringSorter {
private String inputFileName;
//private String line;
public StringSorter(String fileName) {
inputFileName = fileName;
}
public void sortStrings() throws IOException {
FileReader input = new FileReader(inputFileName);
BufferedReader myReader = new BufferedReader(input);
String line, data = "";
String[] words;
int posCount = 0;
while ((line = myReader.readLine()) != null)
data += line;
words = data.split(",");
for(int posi = 0; posi < words.length; posi++) {
if(!Character.isUpperCase(words[posi].charAt(0))) {
posCount++;
}
}
if(posCount > 0) {
System.out.print("Invalid input. Word found which does not start with an uppercase letter.");
}
else {
for (int k = 0; k < words.length; k++) {
for (int i = k - 1; i >= 0; i--) {
if (words[i].charAt(0) < words[k].charAt(0)) {
String temp = words[k];
words[k] = words[i];
words[i] = temp;
k = i;
}
}
}
for(int print = 0; print < words.length - 1; print++){
System.out.print(words[print].trim() + ", ");
}
System.out.print(words[words.length-1]);
}
input.close();
myReader.close();
}
}
import java.io.*;
public class TestStringSorter {
public static void main(String[] args) throws IOException {
StringSorter sorterA = new StringSorter("MyFile.txt");
sorterA.sortStrings();
StringSorter sorterB = new StringSorter("myOtherFile.txt");
sorterB.sortStrings();
StringSorter sorterC = new StringSorter("yetAnotherFile.txt");
sorterC.sortStrings();
}
}
Invalid input. Word found which does not start with an uppercase letter.
Invalid input. Word found which does not start with an uppercase letter.
Invalid input. Word found which does not start with an uppercase letter.
I see what might be the problem. You're splitting on ',', but you have spaces after the comma. So you're going to have a "word" like " Dog", and if you test the first character of that, you're going to get a failure, because a space is not an uppercase letter.
Try splitting on:
words = data.split("[,\\s]+");
that would fix the problem with the spaces in the data.
I see another problem that will cause you to probably not get the results you expect. You're concatenating multiple lines together, but not putting anything between the lines, so the last word on one line is going to combine with the first word on the next. You probably want to put a "," between each line when you concatenate them together.
I guess you want to write your own sort. I'll leave that to you or others to debug. But you could just:
Arrays.sort(words)
Maybe you are putting a space before each word and this is what you are trying to check if it is upper-case...

using scanner to read file but skip blank lines into a 2d array

I am struggling to use scanner class to read in a text file while skipping the blank lines.
Any suggestions?
Scanner sc = new Scanner(new BufferedReader(new FileReader("training2.txt")));
trainingData = new double[48][2];
while(sc.hasNextLine()) {
for (int i=0; i<trainingData.length; i++) {
String[] line = sc.nextLine().trim().split(" ");
if(line.length==0)
{
sc.nextLine();
}else{
for (int j=0; j<line.length; j++) {
trainingData[i][j] = Double.parseDouble(line[j]);
}
}
}
}
if(sc.hasNextLine())
{
sc.nextLine();
}
sc.close();
I am currently trying to get it working like this. But it is not working
Scanner sc = new Scanner(new BufferedReader(new FileReader("training.txt")));
trainingData = new double[48][2];
while(sc.hasNextLine()) {
String line = sc.nextLine().trim();
if(line.length()!=0)
{
for (int i=0; i<trainingData.length; i++) {
String[] line2 = sc.nextLine().trim().split(" ");
for (int j=0; j<line2.length; j++) {
trainingData[i][j] = Double.parseDouble(line2[j]);
}
}
}
}
return trainingData;
while(sc.hasNextLine()) {
for (int i=0; i<trainingData.length; i++) {
String[] line = sc.nextLine().trim().split(" ");
You can't just check the scanner once to see if it has data and then use a loop to read the lines of data. You can't assume that you have 48 lines of data just because you define your array to hold 48 lines of data.
You need to go back to the basics and learn how to read data from a file one line at a time and then you process that data.
Here is a simple example to get you started:
import java.util.*;
public class ScannerTest2
{
public static void main(String args[])
throws Exception
{
String data = "1 2\n\n3 4\n\n5 6\n7 8";
// First attempt
System.out.println("Display All Lines");
Scanner s = new Scanner( data );
while (s.hasNextLine())
{
String line = s.nextLine();
System.out.println( line );
}
// Second attempt
System.out.println("Display non blank lines");
s = new Scanner( data );
while (s.hasNextLine())
{
String line = s.nextLine();
if (line.length() != 0)
{
System.out.println( line );
}
}
// Final attempt
String[][] values = new String[5][2];
int row = 0;
System.out.println("Add data to 2D Array");
s = new Scanner( data );
while (s.hasNextLine())
{
String line = s.nextLine();
if (line.length() != 0)
{
String[] digits = line.split(" ");
values[row] = digits;
row++;
}
}
for (int i = 0; i < values.length; i++)
System.out.println( Arrays.asList(values[i]) );
}
}
The example uses a String variable to simulate data from a file.
The first block of code is how you simply read all lines of data from the file. The logic simply:
invokes the hasNextLine() method so see if there is data
invokes the nextLine() method to get the line of data
display the data that was read
repeats steps 1-3 until there is no data.
Then next block of code simply adds an "if condition" so that you only display non-blank data.
Finally the 3rd block of code is closer to what you want. As it reads each line of data, it splits the data into an array and then adds this array to the 2D array.
This is the part of code you will need to change. You will need to convert the String array to an double array before adding it to your 2D array. So change this code first to get it working. Then once this works make the necessary changes to your real application once you understand the concept.
Note in my code how the last row displays [null, null]. This is why it is not a good idea to use arrays because you never know how big the array should be. If you have less that 5 you get the null values. If you have more than 5 you will get an out of bounds exception.
Try adding this to your code:
sc.skip("(\r\n)");
It will ignore blank lines. For More information: Scanner.skip()

Putting unordered items into an array from a file

I have three CSV files with data that is linked by a string of numbers, I've created a 2d array to store all the data together and have one of the csv files, the data in the other files is not in the same order so I can't simply read line 1 of the file into the first row of the array.
Here's my code
public class grades {
public static void main(String[] args) throws FileNotFoundException
{
int rowc = 0;
String inputLine = "";
String[][] students = new String[10][6];
//Get scanner instance
Scanner scanner = new Scanner(new File("/IRStudents.csv"));
//Set the delimiter used in file
scanner.useDelimiter(",");
while (scanner.hasNextLine()) {
inputLine = scanner.nextLine();
String [] line = inputLine.split(",");
for (int x = 0; x < 2; x++) {
students[rowc][x] = line[x];
}
if (rowc < 9) {
rowc++;
}
else {
break;
}
}
System.out.println(Arrays.deepToString(students));
scanner.close();
Scanner input = new Scanner(new File("/IR101.csv"));
input.useDelimiter(",");
while (input.hasNext()) {
inputLine = input.nextLine();
String[] line = inputLine.split(",");
for (int i = 0; i < 1; i++) {
System.out.println(line[0]);
System.out.println(students[0][i]);
if (line[0].equals(students[0][i])) {
students[2][i] = line[0];
}
}
}
System.out.println(Arrays.deepToString(students));
}
}
I know a lot of it's not very tidy or efficient, but I'd rather it was working. Anyway, how would I loop through the file and add each item to the 3rd column of the array where the corresponding string is that links them?
Thanks.
I hope i understood your problem correctly.
In your case, you could load the 3rd csv into memory and then loop through the arrays (a for inside another for) and check the keys of one array that matches the key on the other (strings that links them) and bind them.
tip: you could initialize the students attributes like this:
students[rowc] = line;

Why is my radix sorting algorithm returning a partially sorted list?

First off I want to point out that this assignment is homework /but/ I am not looking for a direct answer, but rather at a hint or some insight as to why my implementation is not working.
Here is the given: We are provided with a list of words of 7 characters long each and are asked to sort them using the Radix Sorting Algorithm while using queues.
EDIT 1: Updated Code
Here is my code:
import java.util.*;
import java.io.File;
public class RadixSort {
public void radixSort() {
ArrayList<LinkedQueue> arrayOfBins = new ArrayList<LinkedQueue>();
LinkedQueue<String> masterQueue = new LinkedQueue<String>();
LinkedQueue<String> studentQueue = new LinkedQueue<String>();
//Creating the bins
for (int i = 0; i < 26; i++) {
arrayOfBins.add(new LinkedQueue<String>());
}
// Getting the file name and reading the lines from it
try {
Scanner input = new Scanner(System.in);
System.out.print("Enter the file name with its extension: ");
File file = new File(input.nextLine());
input = new Scanner(file);
while (input.hasNextLine()) {
String line = input.nextLine();
masterQueue.enqueue(line);
}
input.close();
} catch (Exception ex) {
ex.printStackTrace();
}
for (int p = 6; p >= 0; p--) {
for (LinkedQueue queue : arrayOfBins) {
queue.clear();
}
while (masterQueue.isEmpty() == false) {
String s = (String) masterQueue.dequeue();
char c = s.charAt(p);
arrayOfBins.get(c-'a').enqueue(s);
}
for (LinkedQueue queue : arrayOfBins) {
studentQueue.append(queue);
}
}
masterQueue = studentQueue;
System.out.println(masterQueue.size());
System.out.println(masterQueue.dequeue());
}
public static void main(String [] args) {
RadixSort sort = new RadixSort();
sort.radixSort();
}
}
I can see so many problems, I'm not sure how you get an answer at all.
Why do you have two nested outermost loops from 0 to 6?
Why don't you ever clear studentQueue?
The j loop doesn't execute as many times as you think it does.
Aside from definite bugs, the program doesn't output anything -- are you just looking at the result in the debugger? Also are you actually allowed to assume that the words will contain no characters besides lowercase letters?

Why am I getting "java.lang.NumberFormatException" when trying to convert this string into an integer?

I have been creating a Java program to encode a message received from the user. Just for some background into how it does this: It is supposed to get the input, split it into characters, then get a set of random numbers from Random.org (true random number generator) equal to the length of the message and then shift the characters of the input by their corresponding shift, or random number, then output the coded message and the shifts. So far I have gotten input, converted it into a string array, checked the quota (Random.org has a quota) and gotten the random numbers. I am getting this error when trying to output the converted shifts (from Strings gotten at the website to ints), I think it is because of a CRLF on the last number (I tried using a regex to fix this, but it didn't work). Here is my code:
public class Encryption_System {
static String originalMessege;
public static void main(String[] args) throws Exception {
System.out.println("Welcome to the encryption system!");
System.out.println("Type your messege below:");
System.out.println("\nHere is your original messege: " + scan() + "\n");
Encrypt code = new Encrypt();
code.Messege(originalMessege);
code.encryptMessege();
}
private static String scan() {
Scanner scan = new Scanner(System.in);
originalMessege = scan.nextLine();
return originalMessege;
}
}
Then there is a second class, where my problem originates. My error comes from the last method (my attempted regex fix is commented out):
public class Encrypt {
private String messege;
private String[] characters;
private URL quotaURL;
private URLConnection conect;
private InputStream quotaInput;
private BufferedReader quotaReader;
private int quota;
private boolean go;
private URL shiftsURL;
private URLConnection conectShifts;
private InputStream shiftsInput;
private BufferedReader shiftsReader;
private int count;
private char[] shifts;
private int[] shiftsInt;
private String shiftsString;
private String[] shiftsStrings;
public void Messege(String x) {
messege = x;
}
private String[] getCharacters() {
characters = messege.split("(?!^)");
return characters;
}
private boolean checkQuota() throws Exception {
quotaURL = new URL("http://www.random.org/quota/?format=plain");
conect = quotaURL.openConnection();
quotaInput = conect.getInputStream();
quotaReader = new BufferedReader(new InputStreamReader(quotaInput));
int quota = Integer.parseInt(quotaReader.readLine());
if (quota >= getCharacters().length)
go = true;
else
go = false;
return go;
}
private char[] Shifts(String[] x1) throws Exception {
String[] messegeArray = x1;
count = 0;
for (int k = 0; k < x1.length; k++) {
if (x1[k].equals(" ")) {
continue;
} else {
count++;
}
}
shifts = new char[count * 3];
if (checkQuota() == true) {
shiftsURL = new URL("http://www.random.org/integers/?num=" + count
+ "&min=1&max=27&col=" + count
+ "&base=10&format=plain&rnd=new");
conectShifts = shiftsURL.openConnection();
shiftsInput = conectShifts.getInputStream();
shiftsReader = new BufferedReader(
new InputStreamReader(shiftsInput));
shiftsReader.read(shifts, 0, count * 3);
}
return shifts;
}
public void encryptMessege() throws Exception {
char[] currentShifts = Shifts(getCharacters());
shiftsString = new String(currentShifts);
// shiftsString.replace("[\t\r\n]", "");
shiftsStrings = shiftsString.split("[( )]");
shiftsInt = new int[shiftsStrings.length];
System.out.println("These are your shifts");
for (int v = 0; v < shiftsInt.length; v++) {
shiftsInt[v] = Integer.parseInt(shiftsStrings[v]);
System.out.println(shiftsInt[v] + " ");
}
}
}
and here is my output:
Welcome to the encryption system!
Type your messege below:
Hello
Here is your original messege: Hello
These are your shifts
3
19
12
3
Exception in thread "main" java.lang.NumberFormatException: For input string: "12
Process completed.
I am just a Java beginner (first year high school comp sci), so thanks for any help!
Your code is failing for me because:
shiftsStrings = shiftsString.split("[( )]");
is not properly splitting the values.
EDIT:
Try This:
public void encryptMessege() throws Exception {
List<Integer> shifts = new ArrayList<Integer>();
StringTokenizer st = new StringTokenizer(new String(Shifts(getCharacters())));
while(st.hasMoreTokens())
{
String token =st.nextToken();
try{
shifts.add(Integer.parseInt(token));
}catch(NumberFormatException e)
{
System.out.println("did not parse: " + token);
}
}
System.out.println("These are your shifts: " + shifts.toString());
}
Note there are a lot of things you should work on in your code.
1) Encapsulating functionality within methods. It gets confusing when you keep all your variables as class level attributes. If you pass them between methods using parameters, you gain easier to read code, and it's easier to test bits of your code.
2) You should start method names with lower case letters. This is common Java coding practice.
If you think it is due to non-number characters in the last number, then before putting it in parseInt use Replace on it with the characters that are non-number (you can use \r, \n and so on too).
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#replace(char, char)
Trim is another useful method, it removes all leading and trailing whitespace.
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#trim()
The problem seems to be originating from here:
shiftsInt[v]= Integer.parseInt(shiftsStrings[v]);
And this fails when in the for loop value of v reaches 4. Remove the expression from the for loop and see if every string in shiftsStrings can actually be parsed to int. Try executing this:
for(int v = 0; v < shiftsStrings.length; v++ ) {
System.out.println(shiftsStrings[v]);
}
If there is something unexpected in the output, the next step would be to find out (and possibly remove) how that value found its place in the array.

Categories