I'm hoping some might be able to suggest an alternate method to a program I'm working on. I've done the below test code to display my query without having to post my full code.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Main {
ArrayList<Students> chemistry = new ArrayList<>();
public void loadClass() {
try (BufferedReader br = new BufferedReader(new FileReader("Chemistry.csv"))) {
String line;
line = br.readLine();
while ((line = br.readLine()) != null) {
String[] values = line.split(",");
try {
chemistry.add(new Students(values[0], values[1], Integer.parseInt(values[2]),
Integer.parseInt(values[3]), Integer.parseInt(values[4])));
} catch (NumberFormatException e) {
System.out.println("You have some text in a number field for entry: " + values[0] + " " + values[1]);
}
}
} catch (FileNotFoundException e) {
System.out.println("The file has not been found in the path \"" + (new File(".").getAbsoluteFile()) + "\"");
System.out.println("Please place the CSV file at this location");
} catch (IOException e) {
System.out.println("Sorry an input/output error has occured.");
e.printStackTrace();
}
System.out.println("students loaded from the file are:");
for (Students pupils : chemistry) {
System.out.println("Student " + pupils.getFirstName() + " " + pupils.getSurname() + " was born in "
+ pupils.getBirthYear() + "/" + pupils.getBirthMonth() + " /"
+ pupils.getBirthDay());
}
System.out.println("\nThe number of students in the class is: " + chemistry.size());
}
public static void main(String[] args) {
Main main = new Main();
main.loadClass();
}
}
public class Students {
private String firstName;
private String surname;
private int birthYear;
private int birthMonth;
private int birthDay;
// All-args constructor, getters and setters omitted for brevity
}
Here is the CSV data I'm using in the Chemistry.csv file
First Name,Surname,Year of Birth,Month of Birth,Day of Birth
Joe,Bloggs,2002,12,8
Jane,Bloggs,2003,11,15
Harry,Smith,2004,10,2
William,Wallace,2001,9,7
Philip,Jones,2002,Aug,9th
As you can see in my CSV file, I've deliberately put a string entry for the month and day in the last line. This is to test my NumberFormatException try/catch.
It works and the user gets prompted that there's an error with that line entry, but this is a small dataset. I'm wondering what I can do when there may be hundreds of lines.
I was thinking that in the catch I could have something that would replace the invalid String with a valid int number. I know in this case I would have to engineer an if/else or switch statement to account for the 12 months and 30(ish) days, however I would just like '0' to be entered for now.
I'm not sure how to pass int 0 as a default value for this as my chemistry.add line parses the file.
I also thought there may be an alternate way of entering the values into my ArrayList so I can put the try/catch around just the Integer.parseInt bits, but again, I'm not sure of another method.
Can anyone suggest a good option to investigate?
EDIT:
After the comment by g00se below, I used this instead and it seemed to work:
while ((line = br.readLine()) != null) {
int third, fourth, fifth;
String[] values = line.split(",");
String first = values[0];
String second = values[1];
try {
third = Integer.parseInt(values[2]);
} catch (NumberFormatException e3) {
third = 0;
}
try {
fourth = Integer.parseInt(values[3]);
} catch (NumberFormatException e4) {
fourth = 0;
}
try {
fifth = Integer.parseInt(values[4]);
} catch (NumberFormatException e5) {
fifth = 0;
}
chemistry.add(new Student(first, second, third, fourth, fifth));
}
Needs some tidying up but at least I have a way forward...
Related
The document I'm scanning says "enter(10);add;(45.76)" on a single line. It's supposed to read over the parenthesis and semicolons and just get the numbers and strings, as well as read the word "enter" before running the code. It manages to read enter correctly and the first number, but after that when scanning for "equation" it instead grabs 45.67) with the parenthesis. If i remove the (45.67) and leave just add; it works and grabs the add. I'm not sure what's going on wrong here. Any help would be appreciated, as well as any advice on how to get this program to scan the next line in the file if there was another one.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;
public class CPLParser {
public double parseScript(String inputFile) throws CPLException{
File file = new File(inputFile);
try (Scanner Filereader = new Scanner(file)){
String line = Filereader.nextLine();
Scanner parser = new Scanner(line);
parser.useDelimiter("\\(|\\)\\;");
String enter = parser.next();
double number = 0;
String equation = " ";
double numberTwo = 0;
double total = 0;
if (!enter.equals("enter")){
throw new InvalidProgramStartException("");
}
while (parser.hasNext()) {
if (parser.hasNextDouble()){
number = parser.nextDouble();
}
if (parser.hasNext()){
equation = parser.next();
}
if (parser.hasNextDouble()){
numberTwo = parser.nextDouble();
}
if (equation == "add") {
double thistotal = number + numberTwo;
total += thistotal;
}
}
System.out.println(equation);
} catch (FileNotFoundException ex) {
System.out.println("Could not find the file");
} catch (InputMismatchException e) {
}
return 0;
}
}
There are few issues in your sample code:
Firstly in java you can not compare string with == you should use Equals method to check equality.
Secondly operation should be done after reading entire line,
also there were blank chars were read by scanner we need to handle that
Please have look into below working code and verify the output.
import java.net.MalformedURLException;
import java.net.URL;
import java.awt.image.*;
import javax.imageio.*;
import javax.swing.*;
import java.io.*;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
System.out.println("Hello World");
try {
Scanner parser = new Scanner("enter(10);add;(45.76)");
parser.useDelimiter("\\(|\\)|\\;");
String enter = parser.next();
System.out.println("enter "+enter);
double number = 0;
String equation = " ";
double numberTwo = 0;
double total = 0;
if (!enter.equals("enter")){
// new InvalidProgramStartException("");
System.out.println("InvalidProgramStartException");
}
while (parser.hasNext()) {
if (parser.hasNextDouble()){
number = parser.nextDouble();
System.out.println("number "+ number);
}
if (parser.hasNext()){
String text= parser.next();
// only set equation if its not blank
if ("".equals(text))
{ System.out.println("equation is Blank "+ equation +"...");}
else
{equation = text;
System.out.println("Setting equation "+ equation);}
}
if (parser.hasNextDouble()){
numberTwo = parser.nextDouble();
System.out.println("numberTwo "+ numberTwo);
}
}
if (equation.equals("add")) {
double thistotal = number + numberTwo;
System.out.println("thistotal "+ thistotal);
System.out.println("total "+ total);
total += thistotal;
System.out.println("total "+ total);
}
System.out.println(equation);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Hope this helps!
import java.util.Scanner;
public class Average
{
public void Average()
{
Scanner in = (new Scanner("J:\\AP Comptuter Science\\Semester 2\\Exeptions\\13.1\\numbers.txt"));
try{
String test = in.nextLine();
} catch(NullPointerException i) {
System.out.println("Error: " + i.getMessage());
}
int total = 0;
int counter = 0;
while(in.hasNextInt()){
total = total + in.nextInt();
counter++;
}
total = total / counter;
System.out.println(total);
}
}
I have a project for my AP Comp class and i did the work according to the notes, but the file "numbers" isn't being read and i get the answer 0 when it should be some huge number.
new Scanner("J:\\AP Comptuter Science\\Semester 2\\Exeptions\\13.1\\numbers.txt")
You are calling Scanner(String source), which does not read the file; it scans the string itself.
What you need is probably public Scanner(File source), as follows:
new Scanner(new File("J:\\AP Comptuter Science\\Semester 2\\Exeptions\\13.1\\numbers.txt"))
You also need to check the path, there almost certainly aren't 5 spaces between "Semester" and "2"
Overall I would strongly urge you to step through your code in a debugger instead of just running. If you had done that, you would have seen that after executing
String test = in.nextLine();
The string test contains the name of the file rather than its contents.
There are other improvements possible, consider posting in the codereview stackexchange after you are able to make it work
Firstly you should correct your path, and probably put it in the same directory as your class files. And instead of providing a path to the scanner you should also give it a file. It should look something like this.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Average
{
public void printAverage(){
File file = new File(""J:\\AP Comptuter Science\\Semester 2\\Exeptions\\13.1\\numbers.txt"");
Scanner scan;
try {
scan = new Scanner(file);
int total = 0, counter = 0;
while(scan.hasNextInt()){
System.out.println("loop");
total = total + scan.nextInt();
counter++;
}
if(counter != 0)
total = total/counter;
System.out.println(total);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
As mentioned earlier, the code has several issues:
a) new Scanner(String) reads the string instead of the file
b) path seems to be incorrect
c) handling of DivideByZero and FileNotFound exceptions
Please see the following code:
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.File;
public class Average{
public void average(){
Scanner in = null;
try{
in = (new Scanner(new File("J:\\AP Comptuter Science\\Semester 2\\Exeptions\\13.1\\numbers.txt")));
String test = in.nextLine();
}
catch(NullPointerException | FileNotFoundException i){
System.out.println("Error: " + i.getMessage());
}
int total = 0;
int counter = 0;
while(in != null && in.hasNextInt())
{
total = total + in.nextInt();
counter++;
}
Float average = null;
if (counter > 0) { //to avoid divide by zero error
average = (float)total / counter;
System.out.println("Average: "+average);
}
}
public static void main(String args[]){
new Average().average();
}
}
This works for only numbers.txt which has integers separated by space as required by the nextInt() method of Scanner class.
I've written an extremely basic program with 3 options. While executing the "Quit" section of the code I get a InputMismatchError. I know that this is because the program is expecting an integer when me/User is giving it a String.
I was just wondering how I would go about setting something like this up.
I've also tried a string to char method but that's also gave me the same error.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
static Scanner S = new Scanner(System.in);
public static void main(String[] args) throws IOException
{
int DisJ, ISJ, User;
ISJ = 1;
DisJ = 2;
String input = "";
// change print outs to appropriate names::::
System.out.println("--Main Menu--");
System.out.println("Display Journeys:" + ISJ);
System.out.println("Suitable Journeys:" + DisJ);
System.out.println("Quit: " );
//User = S.next().charAt(0);
User = S.nextInt();
if (User == 1)
{
System.out.println("You have selected Display Journeys");
try
(BufferedReader ReadFile = new BufferedReader(new FileReader("E:\\input.txt")))
{
String line = null;
while ((line = ReadFile.readLine()) != null)
{
System.out.println(line);
}
}
}
else if (User ==2)
{
System.out.println("You have selected Suitable Journeys");
}
System.out.println("Specify Destination: ");
String destination = S.next();
System.out.println("Specify Max Time (HH:MM): ");
String specificTime = S.next();
// This assigns the first two integers to the string hours
String hours = specificTime.substring(0,2);
//This assigns the last two integers to the string minutes
String minutes = specificTime.substring(3,5);
//integer.parseInt converts the string into an integer
int hours1 = Integer.parseInt(hours);
//integer.parseInt converts the string into an integer
int minutes1 = Integer.parseInt(minutes);
int Time;
// Equation to convert the hh:mm into minutes
Time = (60 * hours1) + minutes1;
System.out.println("Specify number of changes");
int Changes = S.nextInt();
System.out.println( "Destination selected: " + input + "Minutes specified: " + Time + "," + "Number of changes: " + Changes);
int quit;
String Quit = S.next();
if (Quit.equals("Quit")) {
System.out.println("Goodbye!");
System.exit(0);
}
try {
quit = Integer.parseInt(Quit);
}
catch (Exception e)
{
System.out.println("Type Quit to leave");
}
}
}
Is your question that you are not able to make the argument in the if statement true?
Try setting it as a boolean instead of an int / string, and throughout your code just have it changing quit to true/false instead of a number/string.
EDIT: Oh i see. So you just want to make it so that the user can press a key and it will quit, like a "Please enter Y to exit the program"
Do you have a scanner set up?
Wrap yor coe with a try and catch errors to handle them
int quit;
try {
quit = Integer.parseInt(Quit);
} catch (Exception e) {
// handle error...
}
http://beginnersbook.com/2013/04/try-catch-in-java/
To simply check what the user entered just accept a string and check its value like so:
Scanner scanner = new Scanner(System.in);
System.out.print("Quit?");
String text = scanner.nextLine();
if (text.equals("Quit") or text.equals("q")) {
//...
}
I'm trying to use args[0] as an input file, but when I run the program, I keep getting an IndexOutOfBoundsException, although I'm quite sure that args[0] is the correct argument. I ran into this problem with my last program as well, but I can't figure out what I'm doing wrong.
Code:
import java.io.*;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class SortTest {
public static void main(String args[]) throws FileNotFoundException {
try {
Scanner read = new Scanner(new File(args[0]));
while (read.hasNextLine()) {
String name = read.nextLine();
read.nextLine();
String line1 = read.nextLine();
int sh = Integer.parseInt(line1.substring(0,2));
int sm = Integer.parseInt(line1.substring(3));
read.nextLine();
String line2 = read.nextLine();
int fh = Integer.parseInt(line2.substring(0,2));
int fm = Integer.parseInt(line2.substring(3));
if (fh<sh) {
System.out.println("Times not in correct order.");
return;
} else if (fh==sh) {
if (fm<sm) {
System.out.println("Times not in correct order.");
return;
}
} else {
System.out.println(name + "\n" + sh + ":" + sm + "\n" + fh + ":" + fm);
}
}
read.close();
}
catch (FileNotFoundException e) {
System.out.println("Invalid file path.");
}
catch (NoSuchElementException n) {
System.out.println("No readable text in file.");
}
catch (IndexOutOfBoundsException x) {
System.out.println("Proper format is java LectureSortTest <input>");
}
catch (NumberFormatException num) {
System.out.println("File contents not formatted correctly");
}
}
}
I'm trying to create a program that reads in a .txt file with multiple lines containing lists of names. A sample of the test file is below:
Joe Sue Meg Ry Luke
Kay Trey Phil George
I have three classes(also below). Everything works fine, but I would like to know which friend-set has the greatest number of friends (i.e. in the test file Joe would have the greatest number of friends)
The data isn't limited to only two friend-sets though...
import java.io.*;
//Finds the file
public class ReadFileLine {
public static void main(String[] args) throws Exception {
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in),1);
System.out.println("Hello! " + "Please enter the name of your test file: " +
"\n**Hint** for this assignment the file name is: friendsFile.txt\n");
String fileName= keyboard.readLine();
System.out.println(fileName);//
FileLine doLine = new FileLine();
doLine.readList(fileName);
}
}
Class 2:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class InStringFile {
//read the file
private BufferedReader in;
//read each line
private String nextLine;
//handle exceptions
public InStringFile(String filename) {
//line by line input
try {
in = new BufferedReader(new FileReader(filename));
nextLine = in.readLine();
}
catch (FileNotFoundException ee){
System.out.println("We're sorry,\n" +"File " + filename + " cannnot be found.");
System.exit(0);
}
catch (IOException e){
System.out.println("We're sorry,\n" +"File " + filename + " cannot be read.");
System.exit(0);
}
}
//reads the file as string
public String read() {
String current = nextLine;
try {
nextLine = in.readLine();
}
//catch exception
catch (IOException e){
System.out.println("We're sorry, this file cannot be read.");
System.exit(0);
}
return current;
}
public boolean endOfFile() {
return (nextLine == null);
}
//close the file
public void close(){
try {
in.close();
in = null;
}
//catch if file cannot be closed
catch (IOException e){
System.out.println("Problem closing file.");
System.exit(0);
}
}
}
Class 3:
import java.util.StringTokenizer;
public class FileLine {
public void readList (String fileName) throws Exception {
//opens the file and controls file reading
InStringFile reader = new InStringFile(fileName);
System.out.println("\nFile Found!" +
" Now reading from file: " + fileName + "\n");
// line by line read
String line;
do {
line = (reader.read());
//print the friend list
System.out.println("The following friend-set exists: " + line);
this.TokenizeString(line);
}while (!reader.endOfFile());
reader.close();
}
//number of friends
public void TokenizeString(String nameList){
StringTokenizer tokens = new StringTokenizer(nameList);
System.out.println("The number of friends in this friend-set is: " + tokens.countTokens());
}
}
Okay, so I modified the fileLine class to be the following:
import java.util.StringTokenizer;
public class FileLine {
public void readList (String fileName) throws Exception {
//opens the file and controls file reading
InStringFile reader = new InStringFile(fileName);
System.out.println("\nFile Found!" +
" Now reading from file: " + fileName + "\n");
// line by line read
String line;
do {
line = (reader.read());
//print the friend list
System.out.println("The following friend-set exists: " + line);
this.TokenizeString(line, line);
}while (!reader.endOfFile());
reader.close();
}
//number of friends
public void TokenizeString(String nameList, String nameByName) {
StringTokenizer tokens = new StringTokenizer(nameList);
System.out.println("The number of friends in this friend-set is: " + tokens.countTokens());
StringTokenizer st = new StringTokenizer(nameByName, " ");
String firstName = st.nextToken();
System.out.println("Friend-set Leader: " + firstName);
}
}
So now the code returns the first name in each line... I still am stuck on how to store the number of tokens. IF I could do that then I could compare and return the greatest number (right?)...
Let tokenizeString(..) return the number of friends. Then:
int maxFriends = 0;
int maxFriendsLine = 0;
int currentLine = 0;
while (..) {
int friends = tokenizeString(..);
if (friends > maxFriends) {
maxFriendsLine = currentLine;
maxFriends = friends;
}
currentLine++;
}
A few notes:
see if you can use commons-lang FileUtils.readLines(..) or guava Files.readLines(..)
prefer str.split(" ") instead of StringTokenizer
use lower-case methods - that's what the java convention prescribes.