Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

soccersquirt82

macrumors 6502
Original poster
Mar 11, 2008
296
0
I have a homework assignment for Java and I must read a file that has a list of license plates. If the car goes in, it will have a + before the first letter and if it leaves, it will have a - before. I must print out all the cars left in the garage. The license plate numbers are on different lines. This is what I have:

Code:
package garage;
import java.io.*;
import java.util.Scanner;
public class Garage {

	static String[] garagearray = new String[1000];
	static int maxslot = 0;

	static String readlicense(Scanner scan) {
		String license = "";
		license = scan.next();
		return(license);
	}

	public static void main(String[] args) {   

		// Declare the filename we will be looking for   
		String filename = "/Users/crawfordcrenshaw/Documents/garage.txt";   
		FileInputStream stream;  // the stream we will read from


		try {
			// Open the file.  Reading right to left, we
			// (1) create a FileInput Stream, pointing to the file; 
			// (2) assign that stream to the name 'stream'    
			stream = new FileInputStream(filename); 
		} catch (IOException e) {   
			System.out.println("File not found: " + filename);   
			return;  // abort on error   
		}
		Scanner scan = new Scanner(stream);

		// Here the file was opened.  Read in all the characters
		// Connect a stream reader to the stream. 
		// read in all the characters until we hit end-of-file, which is   
		// indicated by a negative return value   

		while(scan.hasNext()){ //looks at every character
			if (scan.nextByte() == 43) { //the plus character
				garagearray[maxslot] = readlicense(scan);
				maxslot++;
				scan.nextLine();
			} else if (scan.nextByte() == 45) {
				String removal = readlicense(scan);
				for (int i = 0; i < maxslot; ++i) {
					if (garagearray[i].equals(removal)) {
						garagearray[i] = "";
						
					}
				}
				scan.nextLine();
			} else {
				scan.nextLine();
			}
		}


		System.out.println("Here is your garage.  Enjoy!");
		for (int i = 0; i < maxslot; ++i) {
			if (!garagearray[i].equals("")) {
				System.out.println(garagearray[i]);
			}
		}

		// close the input file   
		try {   
			stream.close();  
		} catch (IOException e) {     
			System.out.println("Error closing file: " + filename);    
			return;  // abort on error   
		}   
	}
}

I get these exceptions:
Exception in thread "main" java.util.InputMismatchException: For input string: "+63092"
at java.util.Scanner.nextByte(Scanner.java:1812)
at java.util.Scanner.nextByte(Scanner.java:1766)
at garage.Garage.main(Garage.java:39)

Please help! Keep in mind I am a NEW programmer, so fancy lingo will not work.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I don't have the file /Users/crawfordcrenshaw/Documents/garage.txt, which makes this a little tough. I'll try to figure out the format, but if data files are needed to run your program, include them.

-Lee

Edit: First things first:
Code:
        static String readlicense(Scanner scan) {
                String license = "";
                license = scan.next();
                return(license);
        }
So you define a string literal, "", that will be using some memory and assign it to license. You then assign the string returned by scan.next() to license, so that old "" it was pointing to is abandoned, and needs to be cleaned up by the garbage collector (there's a chance this literal will be kept in memory by the runtime, but it's still wasteful). You then return the new string. This could be replaced with:
Code:
static String readlicense(Scanner scan) {
  return scan.next();
}

Or just do scan.next() in-line, as having it in a function isn't buying you much.
 

soccersquirt82

macrumors 6502
Original poster
Mar 11, 2008
296
0
Sorry! This is the EXACT file. . . very short:

+63092
+92874
+10093
+92535
+85404
-85404
-92874
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I'll post again instead of continually editing the same post:
What does this do? Is the next file a list of "actions"?
That's to say, does the garage start empty, and when a +<lic#> appears, that means the car has entered, and when a -<lic#> appears, that means the car has exited? What if -abc appears, but there was never a +abc? What is there's a +abc and car abc is already in the garage? How should this behave?

-Lee
 

soccersquirt82

macrumors 6502
Original poster
Mar 11, 2008
296
0
Yes, that is correct. The teacher told us he will not give us a scenario where you lose a car that was never there.
 

soccersquirt82

macrumors 6502
Original poster
Mar 11, 2008
296
0
In another scenario, there are letters so the program needs to work with letters. Such as:
+M9H34
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
OK, so nextByte is not what you should use, from:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Scanner.html#nextByte()
Throws:
InputMismatchException - if the next token does not match the Integer regular expression, or is out of range

So nextByte is not getting the raw ascii/UTF-8 value of the next character, but it's getting a type byte, which is a 8-bit signed integer value.

Try to use: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Scanner.html#next(java.util.regex.Pattern)
Compile your Pattern at the beginning of your program with:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html#compile(java.lang.String)

If your Pattern just matches any single character, then scan.next(singleChar) where singleChar is your Pattern will return a string with a single character. Then you can compare that to a string literal with .equals.

-Lee

Edit: I didn't enjoy trying to use Pattern, though i'm sure it would be useful. It seems better to just read in a line at a time, and see if the string .startsWith("+"), etc.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
So now that we're past the main problem, there are some other strange things:
Why are garagearray and maxslot static members of Garage and not local variables in main?

What happens when you try to put the 1001st car in the garage?

When you remove an item, you just set it's position to "". You don't "free" a spot up. So if 1 car pulls in and out of the garage 1000 times, the garage is "full" even though there are no cars in it. You then filter empty positions when printing, but this is sort of sloppy.

You have your filename hardcoded. Are you supposed to accept it at the commandline, or as an argument to your program (this is what i did to play with it)?

-Lee
 

soccersquirt82

macrumors 6502
Original poster
Mar 11, 2008
296
0
This is my loop:

Code:
while(scan.hasNext()){ //looks at every character
			if (filename.startsWith("+")) { //the plus character
				garagearray[maxslot] = readlicense(scan);
				maxslot++;
				scan.nextLine();
			} else if (filename.startsWith("-")) {
				String removal = readlicense(scan);
				for (int i = 0; i < maxslot; ++i) {
					if (garagearray[i].equals(removal)) {
						garagearray[i] = "";
						
					}
				}
				scan.nextLine();
			} else {
				scan.nextLine();
			}
		}

It seems that the lines never start with a + or - because it always skips over those lines.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
So why would filename have your file input in it? You never assigned scan.next() or anything to filename. You haven't read anything yet. Read into a String with scan.next(). Then use startsWith on that string. Then you can just use substring to get the rest of the line, after the + or -. Don't worry about readlicense, just get rid of it, it is not saving you any work. Just use substring on the line you read in.

-Lee
 

soccersquirt82

macrumors 6502
Original poster
Mar 11, 2008
296
0
The program works at the beginning. But when it goes into the for loop to look for the car it was equal to, it crashes on the scan.nextLine();. Why does it crash? And how can I empty the element of the array?

Code:
int maxslot=0;
		
		while(scan.hasNext()){ //looks at every character
			String license = scan.next();
			if (license.startsWith("+")) { //the plus character
				garagearray[maxslot] = license.substring(1);
				System.out.println(garagearray[maxslot]);
				maxslot++;
				scan.nextLine();
			 } else if (scan.next().startsWith("-")) {
				String removal = license.substring(1);
				for (int i = 0; i < maxslot; ++i) {
					if (garagearray[i].equals(removal)) {
						garagearray[i] = "";						
					}
				}
				scan.nextLine();
			} else {
				scan.nextLine();
			}
		}
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Is the order of the cars in the garage important? If not, you could just set garagearray to null (why waste the memory on instantiating and storing an empty string? What's it for?), and search the array for the first null position to add a new car to, instead of just putting it in maxslot. Otherwise, if order does matter or you want to keep the array "condensed" you could go to some extra trouble... this was the code i used for it, but it may be overcomplicated for your needs:
Code:
if(i < maxslot-1) System.arraycopy(garagearray,i+1,garagearray,i,garagearray.length-i-1);
garagearray[garagearray.length-1]=null;
--maxslot
break;

Crash is pretty generic. Generally java programs fail when an exception bubbles up past your main function and the JVM catches it. It will normally give you a stack trace with where the original exception was thrown, and each level of the stack that it bubbled up through. What are you getting, specifically?

Right after I copied out that code, i managed to delete the source file, so I don't have access to my code anymore... however, it seems like you could JUST use scan.nextLine() and assign it's return to license. You should be able to eliminate the else part of your if-than-else-if-than-else block there, so that will be a little cleaner.

-Lee
 

soccersquirt82

macrumors 6502
Original poster
Mar 11, 2008
296
0
I changed it a little, but it's now not going into the loop of license.startsWith."+". Why not?

Code:
int maxslot = 0;
		int i = 0;

		while(scan.hasNext()){ //looks at every character
			String license = scan.nextLine();
			System.out.println(license);
			if (license.startsWith("+")) { 
				if (garagearray[i] == null) { //will fill a null string first
					garagearray[i] = license.substring(1);
					break;
				}
				if (garagearray[i] != null){
					garagearray[maxslot] = license.substring(1);
					maxslot++;
					break;
				}
			} else if (license.startsWith("-")) {
				String removal = license.substring(1);
				for (i = 0; i < maxslot; ++i) {
					if (garagearray[i].equals(removal)) {
						garagearray[i] = null;						
					}
				}
				break;
			}
		}

		System.out.println("Here is your garage.  Enjoy!");
		for (int s = 0; s < maxslot; ++s) {
			System.out.println(garagearray[s]);
			}
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
You would need to do a loop in the conditional when startsWith("+") is true. You can loop to garagearray.length, you will eventually find a null. You can incremement maxslot if the position you find the null is equal to maxslot.

-Lee
 

prostuff1

macrumors 65816
Jul 29, 2005
1,482
18
Don't step into the kawoosh...
I'm not sure if your allowed to but i would look into using arraylist. The documentation for it can be found at the link below.

http://java.sun.com/javase/6/docs/api/java/util/ArrayList.html

I would read in one line at a time and check the first char to see if it a plus or a minus sisn. If plus then call the arraylist.add("") and if a minus first search the arraylist and call the arraylist.remove("') function.

Hope that helps
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.