13 Replies - 547 Views - Last Post: 30 January 2012 - 10:20 AM Rate Topic: -----

Topic Sponsor:

#1 jjallenjj  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 20
  • Joined: 07-May 11

File input trouble/patterns

Posted 29 January 2012 - 01:45 PM

I'm having some trouble trying to find the pay way to read a file that has a specific pattern. The file will be set up such that each line will contain a name (<last name>, <first name>), an age (integer), and a yearly salary ($<double>).An Example:
Jones, Mary 63 $73800.00
Hayes, Michael 25 $14000.00
Richardson, Haley 32 $101000.00
Perry, Kendra 40 $53500.00
Duck, Donald 60 $3000000.00

We have to read this into an employee array with employees having the constructor

public Employee ( String a, String b, int c, double salary2){
		lastName = a;
		firstName = b;
		age = c;
		salary = salary2;	
	}


I tried doing it this way but I'm starting to think i need to use some sort of a pattern, not only in the code where I fill the array but also in the counting employees method. Pretty much I'm just stuck on how to read the file with a specific format and receive two strings, an int and a double from each line.
Here is what I have that does not work
import java.io.File;
import java.io.IOException;
import java.util.Scanner;


public class HW2Employees {
	static String fileTyped;
	static int numEmployees;
	static Employee [] employees = new Employee [numEmployees];
	
	

	public static void main(String[] args) throws IOException {
		getName();
		countEmployees();
		//readFile();
		System.out.print(numEmployees);
	}
		
	// get the name of the file
	public static void getName() {
		System.out.println("Enter the name of the file  you want to use?");
		Scanner scan = new Scanner(System.in);
		fileTyped = scan.next();
	}
	
	//find number of employees
	public static void countEmployees () throws IOException{
		File f = new File(fileTyped);
		Scanner scan = new Scanner(f);
		//Find size of array
		int count = 0;
		while (scan.hasNextInt()){
			count++;
		}
		numEmployees = count;
		scan.close();
	}
	
	//Input file into Employee Array
	public static void readFile() throws IOException{
		File f = new File(fileTyped);
		Scanner scanFile = new Scanner(f);
		int line = 0;
		if (scanFile.hasNext()){
			String first = scanFile.next();
			String last = scanFile.next();
			int age = scanFile.nextInt();
			double salary = scanFile.nextDouble();
			employees[line] = new Employee ( first, last, age, salary);
			line++;
		}
			
			
			
		
		}
}



Here is the employee class if it helps:
public class Employee {
	private String lastName;
	private String firstName;
	private int age;
	private double salary;
	
	public Employee ( String a, String b, int c, double salary2){
		lastName = a;
		firstName = b;
		age = c;
		salary = salary2;	
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	

}



Is This A Good Question/Topic? 0
  • +

Replies To: File input trouble/patterns

#2 jon.kiparsky  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1780
  • View blog
  • Posts: 3,358
  • Joined: 19-March 11

Re: File input trouble/patterns

Posted 29 January 2012 - 02:06 PM

The simplest way to execute this would be to split the String (using the String.split() method) and use the elements of the resulting array to construct your Employee. You'll have to do a bit of input checking, at least on the numeric values and the length of the array.
Was This Post Helpful? 3
  • +
  • -

#3 tlhIn`toq  Icon User is offline

  • WillMyCodeWork = !FailedWhenYouTriedIt;
  • member icon

Reputation: 3290
  • View blog
  • Posts: 6,896
  • Joined: 02-June 10

Re: File input trouble/patterns

Posted 29 January 2012 - 02:09 PM

In C# I would use string.split which returns a string[] based on the split character. So if I ged it
Jones, Mary 63 $73800.00

and split on the {space} I would get back

[0] Jones,
[1] Mary
[2] 63
[3] $73800.00


Looks like Java has a string.split, or it can be made easily:
http://www.java-exam...g-split-example

So you would read a line from the file,
Make a new Employee instance
set each property of the Employee to the correct returned array element.
<repeat>

UPDATE: LOL Looks like Jon can type just a tad faster than me!
Was This Post Helpful? 3
  • +
  • -

#4 jon.kiparsky  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1780
  • View blog
  • Posts: 3,358
  • Joined: 19-March 11

Re: File input trouble/patterns

Posted 29 January 2012 - 02:10 PM

Quote

UPDATE: LOL Looks like Jon can type just a tad faster than me!


But you got a bit more detail. Let's call it a draw.
Was This Post Helpful? 2
  • +
  • -

#5 tlhIn`toq  Icon User is offline

  • WillMyCodeWork = !FailedWhenYouTriedIt;
  • member icon

Reputation: 3290
  • View blog
  • Posts: 6,896
  • Joined: 02-June 10

Re: File input trouble/patterns

Posted 29 January 2012 - 02:25 PM

Attached Image
Was This Post Helpful? 2
  • +
  • -

#6 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: File input trouble/patterns

Posted 29 January 2012 - 03:01 PM

You need to take the currency symbol out of your file to use nextDouble. Your code will otherwise work with some minor alterations, although i would use List<Employee> rather than read the whole file first to size the array. If you do read it first, you need to use Scanner.hasNextLine

import java.io.File;
import java.io.IOException;

import java.util.Scanner;


public class HW2Employees {
    static String fileTyped;
    static int numEmployees;
    static Employee[] employees;

    public static void main(String[] args) throws IOException {
        getName();
        countEmployees();
        readFile();
        System.out.print(java.util.Arrays.toString(employees));
    }

    // get the name of the file
    public static void getName() {
        System.out.println("Enter the name of the file  you want to use?");

        Scanner scan = new Scanner(System.in);
        fileTyped = scan.next();
    }

    //find number of employees
    public static void countEmployees() throws IOException {
        File f = new File(fileTyped);
        Scanner scan = new Scanner(f);

        //Find size of array
        int count = 0;

        //while (scan.hasNextInt()) {
        while (scan.hasNextLine()) {
            scan.nextLine();
            count++;
        }

        numEmployees = count;
        employees = new Employee[numEmployees];
        scan.close();
    }

    //Input file into Employee Array
    public static void readFile() throws IOException {
        File f = new File(fileTyped);
        Scanner scanFile = new Scanner(f);
        int line = 0;

        while (scanFile.hasNext()) {
            String first = scanFile.next();
            String last = scanFile.next();
            int age = scanFile.nextInt();
            double salary = scanFile.nextDouble();
            employees[line] = new Employee(first, last, age, salary);
            line++;
        }
    }
}


Was This Post Helpful? 2
  • +
  • -

#7 jjallenjj  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 20
  • Joined: 07-May 11

Re: File input trouble/patterns

Posted 29 January 2012 - 07:07 PM

Thanks guys, made some progess. My countEmployees method will not work so its commented out in this code as Im trying to figure out the other problem
My problem is in cleaning up the $ signs from the string array when I use the split method
-It works for the $ signs up until the last one and I can't figure out which number is wrong. I know its in line 79.
Thanks

import java.io.File;
import java.io.IOException;
import java.util.Scanner;


public class HW2Employees {
	static String fileTyped;
	static int numEmployees = 5;
	static Employee [] employees = new Employee [numEmployees];
	static String [] listArray;
	
	

	public static void main(String[] args) throws IOException {
		getName();
		//countEmployees();
		makeStringArray();
		makeEmployeeArray();
		System.out.println("Done");
	
	}
		
	// get the name of the file
	public static void getName() {
		System.out.println("Enter the name of the file  you want to use?");
		Scanner scan = new Scanner(System.in);
		fileTyped = scan.next();
	}
	
	//find number of employees
	public static void countEmployees () throws IOException{
		File f = new File(fileTyped);
		Scanner scan = new Scanner(f);
		//Find size of array
		int count = 0;
		while (scan.hasNextLine()){
			count++;
		}
		numEmployees = count;
		scan.close();
	}
	
	//Input file into Employee Array
	public static void makeStringArray() throws IOException{
		String list = "";
		File f = new File(fileTyped);
		Scanner scanFile = new Scanner(f);
		// Make array of words in the file seperate by spaces
		// Will have [0] Jones,
		//           [1] Mary
		//           [2] 63
		//           [3] $73800.00
		while ( scanFile.hasNextLine() ){
			list += scanFile.nextLine();
			}
		listArray = list.split(" ");
		//Clean up the commas 
		for ( int i = 0; i < listArray.length-3; i+=4){
			listArray[i] = listArray[i].substring(0, listArray[i].length()-1);
	}
		//Clean up the $
		for (int i = 3; i < listArray.length-4; i+=4 ){
			listArray[i] = listArray[i].substring(1, listArray[i].length());
		}
	}
	
	// Fill array with employee objects from string array
	public static void makeEmployeeArray(){
		int i = 0;
		int a = 0;
		int b = 1;
		int c = 2;
		int d = 3;
				
		while ( i < numEmployees){
			employees[i] = new Employee (listArray[a], 
										 listArray[b],
										 Integer.parseInt(listArray[c]) ,
										 Double.parseDouble(listArray[d]));
			i++;
			if ( a < listArray.length -4) a += 4;
			if ( b < listArray.length -4) b += 4;
			if ( c < listArray.length -4) c += 4;
			if ( d < listArray.length -4) d += 4;			
			
		}
		
			
	}
}

Was This Post Helpful? 0
  • +
  • -

#8 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: File input trouble/patterns

Posted 30 January 2012 - 02:27 AM

Quote

My countEmployees method will not work


I both told you why and showed you what to do about it above - did you not read my post?
Using String.split when you're already using Scanner is usually redundant - the whole point of a Scanner is to split strings
Was This Post Helpful? 1
  • +
  • -

#9 jon.kiparsky  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1780
  • View blog
  • Posts: 3,358
  • Joined: 19-March 11

Re: File input trouble/patterns

Posted 30 January 2012 - 06:28 AM

Quote

Using String.split when you're already using Scanner is usually redundant - the whole point of a Scanner is to split strings


Generally when you're reading a fixed-format file of this sort, it's easier to get each line and process it as an entity. This ensures that you don't get out of sync with the lines if there's an error in the input data. This means you're doing something like
while (scan.hasNextLine())
{ 
  list.add(parse(scan.nextLine());
}


Obviously, splitting the string is not redundant in this case (since you can't use the original scanner on the line).

The alternative, reading the file token by token, is a problem because Scanner doesn't know much about line breaks unless you use nextLine(). If I read token by token, I can't know where the line breaks are. That means that if a file is corrupted in some fashion and one line is wrong, I can't get back in sync, and I lose everything following a corrupt line.
Was This Post Helpful? 1
  • +
  • -

#10 jjallenjj  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 20
  • Joined: 07-May 11

Re: File input trouble/patterns

Posted 30 January 2012 - 06:40 AM

View Postg00se, on 30 January 2012 - 02:27 AM, said:

Quote

My countEmployees method will not work


I both told you why and showed you what to do about it above - did you not read my post?
Using String.split when you're already using Scanner is usually redundant - the whole point of a Scanner is to split strings


Sorry bud didn't realize you changed the code, thought you just quoted it. How was able to do with without the method though as you reccomended
import java.io.File;
import java.io.IOException;
import java.util.Scanner;


public class HW2Employees {
	static String fileTyped;
	static int numEmployees;
	static Employee [] employees = new Employee [numEmployees];
	static String [] listArray;
	
	

	public static void main(String[] args) throws IOException {
		getName();
		makeStringArray();
		makeEmployeeArray();
		System.out.println("Done");
	
	}
		
	// get the name of the file
	public static void getName() {
		System.out.println("Enter the name of the file  you want to use?");
		Scanner scan = new Scanner(System.in);
		fileTyped = scan.next();
	}
	
	//Input file into Employee Array
	public static void makeStringArray() throws IOException{
		String list = "";
		File f = new File(fileTyped);
		Scanner scanFile = new Scanner(f);
		// Make array of words in the file seperate by spaces
		// Will have [0] Jones,
		//           [1] Mary
		//           [2] 63
		//           [3] $73800.00
		while ( scanFile.hasNextLine() ){
			list += scanFile.nextLine();
			}
		listArray = list.split(" ");
		// count employees
		numEmployees = listArray.length/4;
		System.out.println("Number of employees =" + numEmployees);
		//Clean up the commas 
		for ( int i = 0; i < listArray.length-3; i+=4){
			listArray[i] = listArray[i].substring(0, listArray[i].length()-1);
	}
		//Clean up the $
		for (int i = 3; i < listArray.length-4; i+=4 ){
			listArray[i] = listArray[i].substring(1, listArray[i].length());
		}
	}
	
	// Fill array with employee objects from string array
	public static void makeEmployeeArray(){
		int i = 0;
		int a = 0;
		int b = 1;
		int c = 2;
		int d = 3;
				
		while ( i < numEmployees){
			employees[i] = new Employee (listArray[a], 
										 listArray[b],
										 Integer.parseInt(listArray[c]) ,
										 Double.parseDouble(listArray[d]));
			i++;
			if ( a < listArray.length -4) a += 4;
			if ( b < listArray.length -4) b += 4;
			if ( c < listArray.length -4) c += 4;
			if ( d < listArray.length -4) d += 4;			
			
		}
		
			
	}
}


Now I get an array out of bounds on line 65 that I did not have before. Not sure why since all there is there is a while loop.
Was This Post Helpful? 0
  • +
  • -

#11 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: File input trouble/patterns

Posted 30 January 2012 - 08:48 AM

Quote

This ensures that you don't get out of sync with the lines if there's an error in the input data.


You're going to get of sync anyway if there's an error - a ctor expecting n arguments is going to fail with the wrong number. Garbage in -> garbage out. If you're determined to use String.split though, use a different input class, such as BufferedReader, since most of Scanner would be redundant overhead.

Quote

How was able to do with without the method though as you reccomended


I'm not sure what that means, but you've departed radically from what you started with, and what i corrected (and tested incidentally), making it much more complex too...

This post has been edited by g00se: 30 January 2012 - 08:49 AM

Was This Post Helpful? 0
  • +
  • -

#12 jon.kiparsky  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1780
  • View blog
  • Posts: 3,358
  • Joined: 19-March 11

Re: File input trouble/patterns

Posted 30 January 2012 - 09:23 AM

Quote

You're going to get of sync anyway if there's an error


Not at all. Since the data is one record per line, reading line-by-line preserves information and allows simple recovery. If a line fails, you recognize it, log it or raise a red flag, and move on to the next line. Reading token-by-token throws away that information and makes recovery from a format deviation annoying and difficult to do correctly. You'd need some sort of lookahead, basically, to get back in step.

A concrete example might help. Imagine you get this data in your input file:

Jones, Mary 63 $73800.00
Hayes, Michael 25 $14000.00
Richardson, Haley Anne 32 $101000.00
Perry, Kendra 40 $53500.00
Khaled 60 $3000000.00
Mouse, Michael 75 $1,934,456,234.72

How do you recover if you're doing it token-by-token? Going line-by-line, your input validation spots that Richardson is a bad line (line.split().length > 4), so you just drop Richardson, log it, and move on. Then you recognize that Khaled is a bad line (perhaps he's from Afghanistan and uses one name) and you again drop the line, log it, and move on.

This post has been edited by jon.kiparsky: 30 January 2012 - 09:25 AM

Was This Post Helpful? 0
  • +
  • -

#13 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1413
  • View blog
  • Posts: 6,037
  • Joined: 20-September 08

Re: File input trouble/patterns

Posted 30 January 2012 - 09:59 AM

That's true if you're going to allow your application to represent an approximation, based on bad input. My remarks were based on the app being designed to fail on bad input
Was This Post Helpful? 0
  • +
  • -

#14 jon.kiparsky  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1780
  • View blog
  • Posts: 3,358
  • Joined: 19-March 11

Re: File input trouble/patterns

Posted 30 January 2012 - 10:20 AM

View Postg00se, on 30 January 2012 - 11:59 AM, said:

That's true if you're going to allow your application to represent an approximation, based on bad input.


That just seems like ordinary defensive programming to me. Sometimes you want to fail on bad input - a compiler shouldn't try to guess what you mean and proceed! - but this doesn't look like one of those cases to me. I suppose it's up to the client requirements, though.

Wilson's Law: A programmer is someone who looks both ways at a one-way street
Bolker's Corollary: "Only both?"
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1