I know the exception is kind of pointless, but I was trying to learn how to use / create exceptions so I used this. The only problem is for some reason my error message generated by my exception is printing to console twice.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Scanner;
public class Project3
{
public static void main(String[] args)
{
try
{
String inputFileName = null;
if (args.length > 0)
inputFileName = args[0];
File inputFile = FileGetter.getFile(
"Please enter the full path of the input file: ", inputFileName);
String outputFileName = null;
if (args.length > 1)
outputFileName = args[1];
File outputFile = FileGetter.getFile(
"Please enter the full path of the output file: ", outputFileName);
Scanner in = new Scanner(inputFile);
PrintStream out = new PrintStream(outputFile);
Person person = null;
// Read records from input file, get an object from the factory,
// output the class to the output file.
while(in.hasNext())
{
String personRecord = in.nextLine();
person = PersonFactory.getPerson(personRecord);
person.display();
person.output(out);
}
} catch (Exception e)
{
System.err.println(e.getMessage());
}
}
}
import java.util.Scanner;
class Student extends Person
{
private double gpa;
public Student()
{
super();
gpa = 0.0;
}
public Student(String firstName, String lastName, double gpa)
{
super(firstName, lastName);
this.gpa = gpa;
}
public String toString(){
try{
if (gpa >= 0.0 && gpa <= 4.0){
return super.toString() + "\n\tGPA: " + gpa;
}
else {
throw new InvalidGpaException();
}
}
catch (InvalidGpaException e){
System.out.println(e);
return super.toString() + "\n\tGPA: " + gpa;
}
}
public void display()
{
System.out.println("<<Student>>" + this);
}
#Override
public void input(Scanner in)
{
super.input(in);
if (in.hasNextDouble())
{
this.gpa = in.nextDouble();
}
}
class InvalidGpaException extends Exception {
public InvalidGpaException() {
super("Invalid GPA: " + gpa);
}
}
}
This is my console readout. Not sure what's causing the exception to print twice.
project3.Student$InvalidGpaException: Invalid GPA: -4.0
<< Student>>
Id: 2 Doe, Junior
GPA: -4.0
project3.Student$InvalidGpaException: Invalid GPA: -4.0
edit: The main code is on the top. The input is a file designated by the user. What I shown right here is my console printout, not what is returned to the output file. The output file shows the exact same thing minus the error message. The Error message from the exception (which I know is not necessary) is only printed to the console. I don't see where I'm printing it twice.
My guess is that your Person.output() method has a call to toString() in it, which will print the exception before returning the proper string, which doesn't show up because you're outputting it to out.
E: If you want my deduction, here it is: The first error message and normal message are printed out within the call to display(), as it should be. Immediately after that is the output() call, which by the name I guess is meant to do what display() does, except to a file. However, you forgot that the exception is printed directly to System.out, so it appears in the console, while the string that toString() actually returns is written to the file.
What is your main ? what is your INPUT..
Change your exception to something different.
Where are you printing this data ?
<< Student>>
Id: 2 Doe, Junior
GPA: -4.0
Are you sure you aren't calling person.toString() twice ?
My guess is that you are calling toString somewhere in the code you have not shown to us.
Putting in a Thread.dumpStack(); in the toString implementation should tell you from where.
Try changing this:
System.out.println(e);
return super.toString() + "\n\tGPA: " + gpa;
to
System.out.println(e);
(Or something similar)
Related
How properly handle exceptions in scanner? I have different types of inputs and no idea how avoid, for example InputMisMatchException without using try catch block and without ending program.
Many methods with many inputs. How can I resolve this problem and have a clean code? I'm still learning and I'm beginner. Any ideas to short my code? This method seems to be to extensive. I have no experience with refactoring.
For example my addPerson method:
private static void addPerson(Scanner scanner) {
System.out.println("name:");
String name = scanner.next();
System.out.println("surname:");
String surname = scanner.next();
System.out.println("age:");
int age = scanner.nextInt();
System.out.println("height (in CM):");
int height = scanner.nextInt();
System.out.println("weight:");
double weight = scanner.nextDouble();
System.out.println("ADDRESS - city:");
String city = scanner.next();
System.out.println("ADDRESS - zipCode:");
String zipCode = scanner.next();
System.out.println("ADDRESS - street:");
String street = scanner.next();
System.out.println("ADDRESS - home number:");
int homeNumber = scanner.nextInt();
Person person = new Person();
person.setName(name);
person.setSurname(surname);
person.setAge(age);
person.setWeight(weight);
person.setHeight(height);
Address address = new Address(city, zipCode, street, homeNumber);
person.setAddress(address);
personService.add(person);
System.out.println("Person added to the base with id: " + person.getId());
}
You can add throws keyword to your method
public static void addPerson(Scanner scanner) thorws InputMismatchException {
// your code
}
OR you can add try-catch block and this won't end your program.
private static void addPerson(Scanner scanner) {
try{
System.out.println("name:");
String name = scanner.next();
System.out.println("surname:");
String surname = scanner.next();
System.out.println("age:");
int age = scanner.nextInt();
System.out.println("height (in CM):");
int height = scanner.nextInt();
System.out.println("weight:");
double weight = scanner.nextDouble();
System.out.println("ADDRESS - city:");
String city = scanner.next();
System.out.println("ADDRESS - zipCode:");
String zipCode = scanner.next();
System.out.println("ADDRESS - street:");
String street = scanner.next();
System.out.println("ADDRESS - home number:");
int homeNumber = scanner.nextInt();
}
catch(InputMismatchException inputMismatchException){
// you can debug, see what caused issue by adding the code below.
inputMismatchException.printStackTrace();
// or you can add your code to make it user friendly
System.out.println("Uh oh! Your input is not the correct type!");
}
If you want to go the extra mile and improve,
You can create a while-loop for each input and put try-catch block so if the user types something wrong and you get an exception, you have the user try again.
boolean userTypedCorrect = false;
while(userTypedCorrect == false){
try{
// your code
// user typed it correct and didn't get an exception
// change boolean so while loop exits
userTpedCorrect = true;
}
catch(InputMismatchExecption iOrAnyNameIsFine){
System.out.println("Try again!");
// user didn't type it correctly
// boolean doesn't change so it loops
}
}
I would go with try-catch if there's a chance of an exception even you don't have any errors or bugs in your code. (InputMistMatch is a good example)
But if some code requires exception and you KNOW it won't throw an exception when finished coding, you can just use throws. (EX. when you're reading from a .txt file it requires IOExecption but you'll always have the .txt file so it'll never throw an exception)
Tip:
Instead of setting everything through methods,
Person person = new Person();
person.setName(name);
person.setSurname(surname);
person.setAge(age);
person.setWeight(weight);
person.setHeight(height);
you can create your own person constructor in Person.java file or where your Person class is. (I assume you have variables in your Person class)
public class Person{
String name; // this.name
String surname;
int age;
// more variables
public Person(String name, String surname, int age){ // name passed in
// this.name refers to variable we made at top
// name refers to name we passed in
this.name = name;
this.surname = surname;
this.age = age;
}
}
And you make a new person like this
Person John = new Person("John", "Doe", 300);
this.variableName = variableName might be confusing but it's common practice and easy once you understand.
New to Java. I'm having a hard time understanding why my code isn't running. I'm getting a InputMismatchException when I try to run my code.
I did some testing and problems occur if there's white space in my file such as "New York." I've been trying different things such as looping with .hasNextLine() instead of .hasnext() as suggested in other threads but to no avail. Sometimes I can get it to run until the end it gives me a NoSuchElementException. If you could please put me in the right direction, that would help a lot thank you!
import java.util.*;
import java.io.*;
public class StandaloneReport {
public static void main(String[] args) {
String fileInputName;
String fileOutputName;
String firstName;
String lastName;
String houseNumber;
String street;
String city;
String state;
String zip;
String productDescription;
double productPrice;
//Scanner obj1
Scanner input = null;
input = new Scanner(System.in);
System.out.printf("What is the file name?\n");
fileInputName = input.nextLine();
//Print out the name user inputed
System.out.println("File name is: " + fileInputName);
//Read the file
FileReader filereader;
Scanner readInput = null;
try {
readInput = new Scanner(filereader = new FileReader(fileInputName));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (readInput.hasNext())
{
firstName = readInput.next();
lastName = readInput.next();
houseNumber = readInput.next();
street = readInput.next();
city = readInput.nextLine();
state = readInput.next();
zip = readInput.next();
productDescription = readInput.nextLine();
productPrice = readInput.nextDouble();
Textfile looks like this:
Jane
Doe
10
Broadway
New York
NY
10001
Galaxy S10
199.99
2
Samsung Bluetooth
29.99
1
Slim Fit Hard Plastic Case
2.99
2
Charger
17.99
3
Error I get:
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.nextDouble(Unknown Source)
at hey.bcs.hwk.purchases.standalonereport.StandaloneReport.main(StandaloneReport.java:55)
I expected it to read it smoothly so I can print it using PrintStream in another file but I cannot even get past this part.
To be honest your program is problematic in so many ways. But here's an explanation to fix the mismatch issue you mentioned.
readInput.nextLine()
will read the remainder of the current line. So after reading "Broadway" the Scanner stays in the same line and when you call nextLine, the Scanner yields whatever is left in the line for "Broadway", which is an empty String.
To avoid this situation, do
street = readInput.next();
readInput.nextLine();
To drop the current line("Broadway" for example). And then call
city = readInput.nextLine();
That way the program will read "New York" as you expected. As Tom mentioned in the comments, for more details, look at the question asked here.
Apart from the Scanner issue, your program is ambiguous as to where it ends – you did not provide closing brackets. That while loop seems redundant considering that your input is broken: it ceases to match what you have in your code after the "199.99" line. Please put your complete code on there and revise your sample input.
This is for one set of data, one data item per line. You have to make adjustments for multiple sets of data.
int i = 0;
while (readInput.hasNext())
{
if (i == 0)
{
firstName = readInput.nextLine();
}
else if (i == 1)
{
lastName = readInput.nextLine();
}
else if (i == 2)
{
houseNumber = readInput.nextLine();
}
else if (i == 3)
{
street = readInput.nextLine();
}
else if (i == 4)
{
city = readInput.nextLineLine();
}
else if (i == 5)
{
state = readInput.nextLine();
}
else if (i == 6)
{
zip = readInput.nextLine();
}
else if (i == 7)
{
productDescription = readInput.nextLine();
}
else if (i == 8)
{
productPrice = readInput.nextDouble();
}
i += 1;
} // End while
I'm trying to use a NumberFormat object to display a price. I'm very new to programming, my book isn't very helpful, nor is my teacher. I have a class called Product and a class called MyProduct, which is a subclass of Product. In the Product class there is a method called getPrice() that has no parameters. All it does is return the value for price. My task is to create a method in MyProduct called getPrice(NumberFormat nf) that returns the price, but formatted as currency. In the main method, if I use myproduct.getPrice(); I get the price, but unformatted (I know this is because it's calling getPrice() from Product, not getPrice(NumberFormat nf) from MyProduct. My question is what do I put in as an argument to stop getting a compile time error? I've tried getPrice(nf), getPrice(this), getPrice(price), just about anything I can think of and nothing works. Any help would be greatly appreciated and all relevant lines of code are posted below. Thanks in advance.
Below is the MyProduct class
public class MyProduct extends Product{
public MyProduct()
{
super();
}
NumberFormat nf;
public String getPrice(NumberFormat nf) {
this.nf = NumberFormat.getCurrencyInstance();
String priceFormatted = nf.format(price);
return priceFormatted;
}
And here is ProductApp class
public class ProductApp {
public static void main(String args[]) {
// display a welcome message
System.out.println("Welcome to the Product Viewer");
System.out.println();
// create 1 or more line items
Scanner sc = new Scanner(System.in);
String choice = "y";
while (choice.equalsIgnoreCase("y")) {
// get input from user
System.out.print("Enter product code: ");
String productCode = sc.nextLine();
// Use a ProductReader object to get the Product object
ProductDB db = new ProductDB();
MyProduct myproduct = db.getProduct(productCode);
// display the output
String message = "\nPRODUCT\n" +
"Code: " + myproduct.getCode() + "\n" +
"Description: " + myproduct.getDescription() + "\n" +
"Price: " + myproduct.getPrice()+ "\n";
System.out.println(message);
// see if the user wants to continue
System.out.print("Continue? (y/n): ");
choice = sc.nextLine();
System.out.println();
}
System.out.println("Bye!");
The line I need help with is
"Price: " + myproduct.getPrice()+ "\n";
As you are instantiating nf within your getPrice method then I would not bother passing it. Maybe change the method name to something like getPriceAsString defined as
public String getPriceAsString() {
NumberFormat nf = NumberFormat.getCurrencyInstance(); // keep local
String priceFormatted = nf.format(price);
return priceFormatted;
}
Then you can call it as myProduct.getPriceAsString ()
edit
As per you comment
In main do
"Price: " + myproduct.getPrice(NumberFormat.getCurrencyInstance())+ "\n";
And declare the method as
public String getPrice(NumberFormat nf) {
return nf.format(price);
}
I assume that price is correctly set
The program that I am writing is in Java.
I am attempting to make my program read the file "name.txt" and store the values of the text file in an array.
So far I am using a text file that will be read in my main program, a service class called People.java which will be used as a template for my program, and my main program called Names.java which will read the text file and store its values into an array.
name.txt:
John!Doe
Jane!Doe
Mike!Smith
John!Smith
George!Smith
People.java:
public class People
{
String firstname = " ";
String lastname = " ";
public People()
{
firstname = "First Name";
lastname = "Last Name";
}
public People(String firnam, String lasnam)
{
firstname = firnam;
lastname = lasnam;
}
}
Names.java:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Names
{
public static void main(String[]args)
{
String a = " ";
String b = "empty";
String c = "empty";
int counter = 0;
People[]peoplearray=new People[5];
try
{
File names = new File("name.txt");
Scanner read = new Scanner(names);
while(read.hasNext())
{
a = read.next();
StringTokenizer token = new StringTokenizer("!", a);
while(token.hasMoreTokens())
{
b = token.nextToken();
c = token.nextToken();
}
People p = new People(b,c);
peoplearray[counter]=p;
++counter;
}
}
catch(IOException ioe1)
{
System.out.println("There was a problem reading the file.");
}
System.out.println(peoplearray[0]);
}
}
As I show in my program, I tried to print the value of peoplearray[0], but when I do this, my output reads: "empty empty" which are the values I gave String b and String c when I instantiated them.
If the program were working corrrectly, the value of peoplearray[0] should be, "John Doe" as those are the appropriate values in "names.txt"
What can I do to fix this problem?
Thanks!
StringTokenizer(String str, String delim)
is the constructor of StringTokenizer.
You have written it wrong .
Just change your line
StringTokenizer token = new StringTokenizer("!", a); to
StringTokenizer token = new StringTokenizer(a, "!");
Just change it a little bit
StringTokenizer token = new StringTokenizer(a, "!");
while(token.hasMoreTokens())
{
b = token.nextToken();
c = token.nextToken();
}
//do something with them
details:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine<Scanner.java:1540>
at CarReader2.main<CarReader2.java:30>
that's the entirety of the error.
My code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
public class CarReader2 {
String name, speed, acc;
public CarReader2(String carName, String carSpeed, String carAcc){
name = carName;
speed = carSpeed;
acc = carAcc;
}
public String toString(){
return "Name of car: " +name+ "\nSpeed of car: " +speed+"\nAcceleration of car: " +acc+"\n";
}
public static void main(String[] args) {
File file = new File("carlist.txt");
try {
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String c1Name = sc.nextLine();
String c1Speed = sc.nextLine();
String c1Acc = sc.nextLine();
CarReader2 car1 = new CarReader2(c1Name,c1Speed,c1Acc);
car1.speed = c1Speed;
car1.acc = c1Acc;
String c2Name = sc.nextLine();
String c2Speed = sc.nextLine();
String c2Acc = sc.nextLine();
CarReader2 car2 = new CarReader2(c2Name,c1Speed,c1Acc);
car2.speed = c2Speed;
car2.acc = c2Acc;
System.out.println("Information on both cars");
System.out.println("First car:");
System.out.println(car1.toString());
System.out.println("Second car:");
System.out.println(car2.toString());
}
sc.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
It's supposed to read data of 2 cars from a file called carlist.txt, then print the data of both cars in the correct format.
carlist.txt is a text file containing:
jonathan 3 7
dio 8 2
And the program is supposed to print out,
Information on both cars
First car:
Name of car: jonathan
Speed of car: 3
Acceleration of car: 7
Second car:
Name of car: dio
Speed of car: 8
Acceleration of car: 2
The program compiles but doesn't run correctly and shows the error i posted at the very top.
You're using nextLine method wrong. Name, speed and acceleration are in the same line, but you're using 3 nextLine methods to read them. That's what happens when you try to read 6 lines from a file that only has 2 lines in it. use sc.next() instead of sc.nextLine().
You are reading too many lines. There are only two lines in your file, but you are trying to read 6. You can change your text file to:
jonathan
3
7
dio
8
2
or you can read one line and split out the information you want.