Why am I getting "NoSuchElementException" When I can print everything from textfile? - java

I'm able to read everything from the text file and print the data yet I get a "No Such Element" Exception. All the solutions i've found say to use "HasNext" in while loop and yet it doesn't seem to work for me
public void fileReader() throws IOException {
String id;
String brand;
int yearOfManufacture;
int numSeats;
double rentalPerDay;
double insurancePerDay;
double serviceFee;
double discount;
String model;
String type;
String color;
ArrayList<Vehicle> vehicleArray = new ArrayList<>();
File file = new File("C:/Users/jockg/Downloads/Fleet (1).csv");
Scanner scan = new Scanner(file);
scan.useDelimiter("n/n");
while (scan.hasNext() || scan.hasNextDouble() || scan.hasNextInt()) {
id = scan.next();
System.out.println(id);
brand = scan.next();
System.out.println(brand);
model = scan.next();
System.out.println(model);
type = scan.next();
System.out.println(type);
yearOfManufacture = Integer.parseInt(scan.next());
System.out.println(yearOfManufacture);
numSeats = Integer.parseInt(scan.next());
System.out.println(numSeats);
color = scan.next();
System.out.println(color);
rentalPerDay = Double.parseDouble(scan.next());
System.out.println(rentalPerDay);
insurancePerDay = Double.parseDouble(scan.next());
System.out.println(insurancePerDay);
serviceFee = Double.parseDouble(scan.next());
System.out.println(serviceFee);
if (scan.next().equals("N/A")) {
discount = 0;
} else {
discount = Double.parseDouble(scan.next());
}
System.out.println(discount);
Car newCar = new Car(id, brand, yearOfManufacture, numSeats, rentalPerDay, insurancePerDay, serviceFee,
discount, model, type, color);
vehicleArray.add(newCar);
}
}
C001,Toyota,Yaris,Sedan,2012,4,Blue,50,15,10,10
C002,Toyota,Corolla,Hatch,2020,4,White,45,20,10,10
C003,Toyota,Kluger,SUV,2019,7,Grey,70,20,20,10
C004,Audi,A3,Sedan,2015,5,Red,65,10,20,10
C005,Holden,Cruze,Hatch,2020,4,Green,70,10,10,10
C006,BMW,X5,SUV,2018,7,White,100,25,20,10
C007,BMW,320i,Sedan,2021,5,Grey,75,10,15,N/A
C008,Ford,Focus,Sedan,2014,5,Red,45,10,10,N/A
C009,Ford,Puma,SUV,2015,5,Black,70,20,15,20
This is the Exception I get:

your CSV has actually two delimiters: comma and new line. Try: scan.useDelimiter(",|\\R");
discount is read twice for numeric values, try:
String discountStr = scan.next();
discount = discountStr.equals("N/A") ? 0 : Double.parseDouble(discountStr);

if (scan.next().equals("N/A")
might be your problem here. from what it looks like, this is not doing what you intend on doing.
When you call scan.next() it will read regardless of whether it is equal to "N/A"
you put an else statement after this and say discount = Double.parseDouble(scan.next() and I presume you are talking about the same scan.next() that you called in the initial if statement, but that line has already passed. You need to store this scan.next() in a variable and then check if it is "N/A".

Related

String Manipulation ? and OOP issue JAVA

Henlo,
My issue is that I have to create two objects using two different constructors:
public SmartHome(int size) {
smrtDev = new SmartDevice[size];
}
public SmartHome(SmartDevice[] values) {
smrtDev = values;
}
For the first one I've achieved it as so with this code snippet:
Scanner myObj = new Scanner(System.in);
System.out.println("Enter size of SmartHome: ");
int size = myObj.nextInt();
SmartHome firstSmartHomeObject = new SmartHome(size);
for(int i=0; i<size;i++) {
System.out.println("\nName: ");
String name = myObj.next();
System.out.println("\nLocation: ");
double location = myObj.nextDouble();
System.out.println("\nIs on?: ");
boolean switchedOn = myObj.nextBoolean();
firstSmartHomeObject.insertDevice(name, location, switchedOn);
}
The second insertDevice() takes in SmartDevice dev
and I have no idea how to do so. What I've attempted is to do SmartDevice dvc+(i) = new SmartDevice(name, location, switchedOn); at the end of the loop but have no idea on how to create dvc1/dvc2/dvc3 etc... , not even sure if this would be the correct way to tacle this problem :(
Supposed to do: :s
SmartDevice dvc = new SmartDevice(name, location, switchedOn); secondSmartHomeObject.insertDevice(dvc);

Java parsing multiple files

I need to parse multiple files and get access to the object's methods outside of where they were initialized.
This is my code:
public static void main(String[] args) {
try {
File Attrationfile = new File("attractions.txt");
Scanner attractionscanner = null;
attractionscanner = new Scanner(Attrationfile);
while (attractionscanner.hasNext()) {
String nextline = attractionscanner.nextLine();
String[] Attractioncomponents = nextline.split("#");
String ridename =Attractioncomponents[0];
int price = Integer.parseInt(Attractioncomponents[1]);
String type = Attractioncomponents[2];
int unknown = Integer.parseInt(Attractioncomponents[3]) ;
double speed = Attractioncomponents.length <= 4 ? 0 :
Double.parseDouble(Attractioncomponents[4]);
RollerCoaster rollerCoaster = new RollerCoaster(ridename, price , unknown, speed);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
File Customerfile = new File("customers.txt");
Scanner Customerscanner = new Scanner(Customerfile);
while (Customerscanner.hasNext()) {
String nextline = Customerscanner.nextLine();
String[] Customercomponents = nextline.split("#");
int accountnumber =Integer.parseInt(Customercomponents[0]);
String name = Customercomponents[1];
int age = Integer.parseInt(Customercomponents[2]) ;
int balance = Integer.parseInt(Customercomponents[3]) ;
String discount = Customercomponents.length <= 4
? String.valueOf(0) : Customercomponents[4];
Customer customer= new Customer(accountnumber,name, age, balance, discount);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
This works but I can't get access to the objects outside of their loops. I am not sure how the Сustomer class would get information about the roller coaster, such as the name and price. For example, if the customer and rollercoaster objects were in the same area, I would be able to update the customer balance by taking away rollercoaster.getprice from the customer.getbalance, and setting customer.setbalance to the value of the calculation. As you have probably already gathered, I am a beginner, so I am probably going about this in the wrong way - thanks.
You can change the scope for those variables by declaring them at the start of the main method.
public static void main(String[] args) {
Customer customer = null;
RollerCoaster rollerCoaster = null;
try {
File Attrationfile = new File("attractions.txt");
Scanner attractionscanner = null;
attractionscanner = new Scanner(Attrationfile);
while (attractionscanner.hasNext()) {
String nextline = attractionscanner.nextLine();
String[] Attractioncomponents = nextline.split("#");
String ridename =Attractioncomponents[0];
int price = Integer.parseInt(Attractioncomponents[1]);
String type = Attractioncomponents[2];
int unknown = Integer.parseInt(Attractioncomponents[3]) ;
double speed = Attractioncomponents.length <= 4 ? 0 :
Double.parseDouble(Attractioncomponents[4]);
rollerCoaster = new RollerCoaster(ridename, price , unknown, speed);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
File Customerfile = new File("customers.txt");
Scanner Customerscanner = new Scanner(Customerfile);
while (Customerscanner.hasNext()) {
String nextline = Customerscanner.nextLine();
String[] Customercomponents = nextline.split("#");
int accountnumber =Integer.parseInt(Customercomponents[0]);
String name = Customercomponents[1];
int age = Integer.parseInt(Customercomponents[2]) ;
int balance = Integer.parseInt(Customercomponents[3]) ;
String discount = Customercomponents.length <= 4 ? String.valueOf(0) :
Customercomponents[4];
customer= new Customer(accountnumber,name , age , balance, discount);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Welcome to SO! As Hovercraft pointed out, the objects are declared within the scope of the loop, meaning you can't access them outside of it as you noticed. Also, they are overwritten on every iteration, since you declare and initialize the object on every pass. Consider using an ArrayList like so (here just for the customers):
ArrayList<Customer> customerList = new ArrayList<>();
try {
while (customerScanner.hasNext()) {
// ...
customerList.add(new Customer(accountnumber,name, age, balance, discount));
}
} catch (...) {
// ...
}
Here's the doc for the ArrayList. <T> is a generic type, which for you means that you can have an ArrayList<Customer>, ArrayList<RollerCoaster>, ArrayList<String> ...
Sidenote: By convention, variable names start with a lowercase letter, like Scanner customerScanner instead of Scanner Customerscanner.
Is it a question of scope? Try to declare an object outside the body of the loop.
Because in Java, the brace is a scope. The more nested braces, the smaller the scope. You can try to declare the objects you need to call in the external scope in the same or larger scope
String type = null;
RollerCoaster rollerCoaster = null;
while (attractionscanner.hasNext()) {
String nextline = attractionscanner.nextLine();
String[] Attractioncomponents = nextline.split("#");
String ridename =Attractioncomponents[0];
int price = Integer.parseInt(Attractioncomponents[1]);
type = Attractioncomponents[2];
int unknown = Integer.parseInt(Attractioncomponents[3]) ;
double speed = Attractioncomponents.length <= 4 ? 0 :
Double.parseDouble(Attractioncomponents[4]);
rollerCoaster = new RollerCoaster(ridename, price , unknown, speed);
}

specifying the path for input data and output data

I am new in java and I have to use the code below but the code it does work because I have to specifying the path for input data and output data. The code is got it from the internet. please help me
class Svm_scale
{
private BufferedReader rewind(BufferedReader fp, String filename) throws IOException
{
fp.close();
return new BufferedReader(new FileReader(filename));
}
private void output_target(double value)
{
LnCount++;
if(y_scaling)
{
if(value == y_min)
value = y_lower;
else if(value == y_max)
value = y_upper;
else
value = y_lower + (y_upper-y_lower) *
(value-y_min) / (y_max-y_min);
}
formatterscaled.format(value+" ");
System.out.println(" Line Number "+LnCount + " ");
}
private void output(int index, double value)
{
count++;
double Threshold1=0,Threshold2=0;
Threshold1= Avg[index]+(STDV[index]/2);
Threshold2= Avg[index]-(STDV[index]/2);
if(value > Threshold1 )
value = 2;
else if(value < Threshold2 )
value = -2;
else
value = 0;
formatterscaled.format( formatter.format(value) + ",");
// System.out.println(" Counter "+count);
// }
}
String save_filename =Save1; // = null?
String restore_filename =null;
String scale_data_filename =Disc; // set this to the path where the output should be stored, e.g. = "C:\\temp\\scaled";
String data_filename =Libsvm; // set this to the path where the input can be get, e.g. = "C:\\temp\\inputdata"
These are the Strings you need to adapt in order that the program can read and write. Save1, Disc, Libsvm are not in your code, so it can only be guessed where they come from.
data_filename and scale_data_filename are required. save_filename seems to be optional and may be set to null.

Returning a double from a method

I am currently writing a program that will read through a designated text file that checks the transaction values of each buy/sell/summary and checks the arithmetic such that if the transactions from the buy and sell statements do not equal the total transaction amount that was given in the summary then it outputs an error and closes the program. But currently my method scanMoneyValue has an error that says it's not returning a double, when in fact it is. Is there a different way I should go about returning the values from my method? Here is my code for reference:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
public class RecurrsionFileChecker {
public static void main(String[] args) {
int result;
//File Chooser Window
JFileChooser chooser = new JFileChooser("/home/nick/workspace/CS 1410-001/src/assignment03");
chooser.setDialogTitle("Please choose a file to be checked");
result = chooser.showOpenDialog(null);
//User Cancelled the chooser
if (result == JFileChooser.CANCEL_OPTION)
return;
File inputfile = chooser.getSelectedFile();
try
{
Scanner in = new Scanner(inputfile);
//Call Method to look at next transaction
scanNextTransaction(in);
}
catch (IOException e)
{
System.out.println("Could not read file: " + inputfile);
}
}
/**
* Returns double if the parameter Scanner has an error that does,
* not match the summary before it.
*
* #param s Any scanner
* #return double if Summaries don't match.
*/
public static double scanNextTransaction(Scanner s)
{
String buy, sell, summary, date;
double amount = 0, referenceValue, total = 0;
summary = s.next();
date = s.next();
referenceValue = scanMoneyValue(s);
while (s.hasNext())
{
if (s.next() == "Buy")
{
date = s.next();
amount = scanMoneyValue(s);
}
if(s.next() == "Sell")
{
date = s.next();
amount = scanMoneyValue(s);
}
if(s.next() == "Summary")
{
amount = scanSubSummary(s);
}
//add the transactions
total = total + amount;
}
return total;
}
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
if(dollar.charAt(0) == '$')
{ //convert string to a double
String amount = dollar.substring(1);
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
}
public static double scanSubSummary(Scanner sub)
{
String summaryDate, transDate, transType;
int summarySubEntries, count = 0;
double transValue, summaryValue = 0, totalValue = 0, summaryAmount;
summaryDate = sub.next();
summaryAmount = scanMoneyValue(sub);
summarySubEntries = sub.nextInt();
while (count != summarySubEntries)
{
transType = sub.next();
if (transType == "Summary")
{
summaryValue = scanSubSummary(sub);
}
transValue = scanMoneyValue(sub);
totalValue = transValue + totalValue + summaryValue;
count++;
}
if (totalValue != summaryAmount)
{
System.out.print("Summary error on " + summaryDate + ".");
System.out.println("Amount is $" + summaryAmount + ", " + "should be $" + totalValue + ".");
}
return totalValue;
}
}
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
if(dollar.charAt(0) == '$')
{ //convert string to a double
String amount = dollar.substring(1);
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
}
If the if condition fails then there's no return statement. You have a return inside of the condition but not outside. You'll need to add a return statement at the end, or throw an exception if not having a dollar sign is an error.
Okay, looking at the only relevant part of your code:
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
if(dollar.charAt(0) == '$')
{ //convert string to a double
String amount = dollar.substring(1);
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
}
You do return a value if dollar starts with a $... but what do you expect to happen if it doesn't start with $? Currently you reach the end of the method without returning anything, which isn't valid.
You should probably throw an exception, if this is unexpected data that you can't actually handle.
Additionally, you shouldn't really use double for currency values anyway, due to the nature of binary floating point types. Consider using BigDecimal instead.
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
if(dollar.charAt(0) == '$')
{ //convert string to a double
String amount = dollar.substring(1);
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
//NEED RETURN STATEMENT HERE
}
The error you get is because when you write a function all branches of that function must return a value of the correct type. In your case, if the if-statement fails it hits the end of the function without returning anything.
Its better to change it on
public static double scanMoneyValue(Scanner in)
{
String dollar = in.next();
String amount = dollar.replaceAll("[^\\d.]+", "")
double complete = Double.parseDouble(amount);
complete = complete * 100;
return complete;
}
link on explain - Parsing a currency String in java

Error when reading instances

I have been working on this sort of ATM (With a maximum of 50 customers), where I read a .txt file, and then create multiple instances, store them in an array, so that other classes can call on them.
When I read the file, only the last customer's information are inputted correctly - I can't ever get the first few customers to have their output correct.
There are multiple methods for each 'Set', just in case the field says 'none', so that I can leave it as a
Double.NaN or null, for example.
I have researched on a few websites, and there wasn't very much on storing instances in arrays, although on one website, it said that I should declare it just like a normal array.
private static String firstname = "";
private static String lastname = "";
private static int sin = 0;
private static int year = 0;
private static int month = 0;
private static int day = 0;
private static double sbalance = 0.0;
private static double cbalance = 0.0;
private static double cardbal = 0.0;
private static boolean confirm = false;
public int customernumber;
public static customer [] customerarray = new customer [50];
public static void readfile(){
String sb = "";
String cb = "";
String ca = "";
int counter = 0;
String thisLine;
try {
BufferedReader br = new BufferedReader(new FileReader("bankinfo.txt"));
while ((thisLine = br.readLine()) != null) {
customerarray[counter].setLastName(thisLine);
System.out.print (customerarray[counter].getLastName());
customerarray[counter].setFirstName(br.readLine());
System.out.print (customerarray[counter].getFirstName());
customerarray[counter].setSin(Integer.parseInt(br.readLine()));
System.out.print (customerarray[counter].getSin());
customerarray[counter].setYear(Integer.parseInt(br.readLine()));
System.out.print (customerarray[counter].getYear());
customerarray[counter].setMonth(Integer.parseInt(br.readLine()));
System.out.print (customerarray[counter].getMonth());
customerarray[counter].setDay(Integer.parseInt(br.readLine()));
System.out.print (customerarray[counter].getDay());
sb = br.readLine();
if (sb.equals("none")){
customerarray[counter].setSBalance("none") ;
System.out.print (customerarray[counter].getSBalance());
}
else {
customerarray[counter].setSBalance(Double.parseDouble(sb));
System.out.print (customerarray[counter].getSBalance());
}
cb = br.readLine();
if (cb.equals ("none")){
customerarray[counter].setCBalance ("none");
}
else if (cb != "none"){
customerarray[counter].setCBalance(Double.parseDouble(cb));
}
else{
System.out.print ("error CBalance");
}
ca = br.readLine();
if (ca.equals("none")){
customerarray[counter].setSBalance("none") ;
}
else {
customerarray[counter].setCardbal(Double.parseDouble(ca));
}
counter = counter + 1;
}
br.close();
}
catch (IOException e) {
System.err.println("Error: " + e);
}
}
The text file is fairly simple- it is composed of 9 fields for each customer.
If they do not have a certain account, it is listed as 'none', and when the reader reads them, it uses a variant method with a String input, and sets the double = Double.NaN();
The following is an example of the text file.
Each customer has 9 fields.
Tam
Christian
984635684
1996
6
12
none
10233.52
none
Yang
Wesley
324917400
1996
8
1
3233.36
none
none
Lin
Sophia
1984
1985
5
6
912.12
58.96
95.63
I don't see where you're instantiating each individual location of your customer[] with actual customer objects.
Add this line before after the start of your while loop:
customerarray[counter] = new customer();
When creating an object array, all of the elements in it default to null. You can't dereference null, so you're running into issues.

Categories

Resources