java project need assistance

Joined
Nov 26, 2006
Messages
620
Ok so im taking intermediate java and I remember nil from intro to java. I've got to make a program that reads a text file (the file was provided by the professor), then Ive got to use the stingtokenizer method to break the the file into pieces (using , as the delimiter). Then I have to output to the screen and to a file each student and their information (the file is a list of students and their classes). Theres actually a little more than that but right now thats all im concerned with...got to take it one step at a time.

Right now Im building the read method for my class which should find the file, read the file, and then tokenize it. But right now I netbeans is saying "cannot find symbol" for the stringtokenizer, hasmoretoken, and nexttoken methods. Heres what ive got so far.
 
don't know much about java, but do you need to put:

Code:
import java.util.*;

at the top?
 
don't know much about java, but do you need to put:

Code:
import java.util.*;

at the top?

I didn't try this before because I thought string tokenizer was part of java.lang which is always imported. but I tried it anyway, and your right it does remove the cannot find symbol error! Thank you. Here is my updated code, I dont have a return value yet because I dont know what i should do. I need help understanding the concept of what Im doing right now.
 
I'm just really getting into programming myself. And I have not done anything with java yet. But don't you have to list where the file you want to read is located?
 
Ok, so this is what I did. let me see if I can explain...this is actually my first java program in a really long time, but I have done a lot of c/c++ and php.

Code:
 public static void main(String[] args) throws IOException {

          //Set your variables
        BufferedReader input = new BufferedReader(new FileReader("students.txt"));
        BufferedWriter output = new BufferedWriter(new FileWriter("out.txt"));
        
        String studentinfo;
          //Basically this while reads each line until the end of the students.txt file
        while ((studentinfo = input.readLine()) != null) {
              //This puts each line from the students.txt file in the line variable
            StringTokenizer line = new StringTokenizer(studentinfo);
              //Sees the first thing in line and keeps looping until the line is empty
            while (line.hasMoreTokens()) {
                  //Since nextToken() pops off the next token in line you need
                  //need to store that token in the "s" variable
                String s = line.nextToken();
                  //Print out the token
                System.out.println(s);
                  //Write the token to a file
                output.write(s);
            }

        }
        //Close both and no need to return anything.
        input.close();
        output.close();
    }
 
Thanks ThatDood that helped a bunch. Ive still got a bunch of questions but I'll post it in the morning with updated code.
 
as far as the string tokenizer goes when I use the nextToken method is there anyway to set the nuumber of characters in the string as the delimiter? On the file this program has to read almost all the tokens have a delimiter of "," except for the last class and the start of the next persons name there is no delimiter. heres a bit of the file so you understand what Im saying

Gallo,Perez,847544848,fall,2008,cop3804,caf3223,tgr4334,sdt4221Puntillita,Martinez,...

see the green text is the start of the next student and there is no delimiter between it and the previous class code, but every class code is the exact same length is there anyway to make it end the token after exactly 7 character?

btw heres some updated code, ive decided to make two seperate classes.
package homework1;
 
Can you post more of the file that you're trying to parse? I can't tell if you have records for more than one person appearing on the same line. If so, things'll be trickier.
 
Can you post more of the file that you're trying to parse? I can't tell if you have records for more than one person appearing on the same line. If so, things'll be trickier.

yes there are records for multiple people in one line heres the whole file, except its actually all one big line
 
Are you sure it's all on one line, and not some weird CR/LF interpretation thing?

Because then parsing the file is much harder if it's all one line
 
Are you sure it's all on one line, and not some weird CR/LF interpretation thing?

Because then parsing the file is much harder if it's all one line

actually your right its not a single line, I was opening it in notepad. when I open it in wordpad it shows it seperated like I showed before. So should I make return the delimiter? Whats the syntax for that?
 
From your code above...

Code:
        while ((studentinfo = input.readLine()) != null) {
        }

That already reads files line by line, a line to java.io.BufferedReader.readLine being anything terminated by '\n', '\r', or '\r\n'. Of course, your while loops currently don't do anything.
 
I'm not sure if you've done Vectors yet, but I've done something similar to your assignment.

Code:
public static void loadBookDatabase()
    {
    	try
    	{
			Scanner loadBookDb = new Scanner(new File("books.db"));
		 	data = new Vector();
		 
			do
			{	
				String	book = loadBookDb.nextLine();
				StringTokenizer split = new StringTokenizer(book, "|");
				Vector	row = new Vector();		
				do
				{
					row.addElement(split.nextToken());
				}
				while(split.hasMoreTokens());
				
				data.addElement(row);
			}
			while(loadBookDb.hasNext());
    	}
    	catch(IOException e)
    	{
    		System.out.println("IO File Error! Check books.db!"+e);
    	}	
    }

Hope this will clarify some stuff up.
 
Here is a basic parser while loop. I've added a section that when a word token is found it checks the token against a few conditional statements. As a parser for a game's log file, a creature's name is always uppercase and can be 1 to 4 words long, so when the first character of a word token is uppercase this parser will loop until it has the creature's whole name. By using a while or for loop similar to this example you should be able to complete your assignment.

Code:
try {
	while (input.nextToken() != StreamTokenizer.TT_EOF ) {
		if (input.ttype == StreamTokenizer.TT_EOL) { }	//Do nothing, end of line
		else if (input.ttype == StreamTokenizer.TT_WORD){
			System.out.println("Found string: "+ input.sval);	//DEBUG

			if (input.sval.equalsIgnoreCase("hello")) {
				// This word is "hello"
			}
			else if (Character.isDefined(input.sval.charAt(0)) && Character.isUpperCase(input.sval.charAt(0))) {
				int count = 0;
				String creature = input.sval;
				while (count < 4 && input.nextToken() != StreamTokenizer.TT_EOL) {
					if (input.ttype == StreamTokenizer.TT_WORD && Character.isUpperCase(input.sval.charAt(0))) {
						creature = creature + " " + input.sval;
						count++;
					}
					else count = 4;  // This Character is not uppercase, so end the loop.
				}
				creature = creature.trim();
			}
		}
		else if (input.ttype == StreamTokenizer.TT_NUMBER){
			System.out.println("Found double: "+ input.nval);	//DEBUG
		}
		else {
			System.out.println("Found Ordinary Character: "+ (char)input.ttype);	//DEBUG
		}
	}
}
catch (IOException e) {
	System.out.println("An Error Occured: " + e);
	System.exit(1);
}


You can change what symbols should be parsed or excluded. By default, a tokenizer will treat undefined symbols as spaces (excluding them). I've thrown some examples of how you can customize the tokenizer below.

Code:
StringTokenizer input = new StringTokenizer(studentinfo);

	// By default +, -, *, (, and ) are ordinary characters
	// but / is not an ordinary character.
	// We add / to the ordinary character list.
	input.ordinaryChar('/');
	input.ordinaryChar('-');
	input.quoteChar('"');
	// input.quoteChar('\u00A0');
	input.commentChar(':');
	input.eolIsSignificant(true);
	input.slashSlashComments(true);
	input.parseNumbers();

	input.ordinaryChars('0', '9');   // This is a trick you can use when you want to force numbers to be read as words
	input.wordChars('0', '9');




You most likely wont need this anytime soon, but you can also create a list of words to ignore. This is useful if you want speed up the parse of a large log file with a lot of repeated common words.

Code:
	//keywords for lines to ignore.
	Set<String> keywords = new HashSet<String>();
	keywords.add("cast");
	keywords.add("casts");
	keywords.add("healed");
	keywords.add("From");	//Player msg
	keywords.add("Paging");	//Player msg
	keywords.add("paging");	//Player msg
	keywords.add("This");	//look or location
	keywords.add("seems");	//look or location
	keywords.add("Broadcast");


...
		else if (input.ttype == StreamTokenizer.TT_WORD) {
			//if (keywords.contains(input.sval)) { }	//ignore this word
			if (keywords.contains(input.sval)) {
				while (input.nextToken() != StreamTokenizer.TT_EOL) {}	//ignore this entire line
		        }
			else if (input.sval.equalsIgnoreCase("hello")) {
				// This word is "hello"
			}
...
 
I offer this program below. It shows how to parse input streams, read and write files, and make HTTP GET requests.

It basicly takes a newegg item number from the command line, or in batches from a file. Using the number it fetches the webpage and parses out the name of the item and the price. It can take inputs from whitespace (spaces, EOL, etc) delimited files or a command line argument and it can write to stdout or a file as well. I forgot why I originally wrote this program, but it was an example for someone else on these boards.

Linkage:

http://www.devshaven.com/files/NeweggItemGrabber.jar
Source is included inside you can unpack it with any archiving utility that supports .zip
You can run the jar using "java -jar" command.

FWIW StringTokenizer is deprecated in favor of using regex, however there are some performance issues (not that you'll notice on small things). If you are writing text to a file it is easiest to use a Fileoutputstream decorated with a PrintWriter set to autoflush.
 
ok so last night we went over the project again in class and it really straightened alot of things out, this is much easier than I originally thought. Ive decided to make it in a single class. Right now ive got the program working somewhat it reads the file tokenizes it and displays the tokens to the screen. Im getting there
 
Ok here is some updated code. it works like it should save for one thing. Instead of reading the next line after it displays the first line it always reads the first line. How should I go about making it read the first line display it then read the next line display it... so on and so forth until there are no more lines. I thought thats what the while loop in the main method was doing but I guess Im mistaken.
 
Exactly which part of that loop are you expecting to read a line from the file?

By the way, your code needs a lot of work... Temporary values should be in local variables. Methods should take arguments and return values rather than communicating through class variables. displayout() and writefile() spend most of their time calculating the same thing, but don't share any code. You're recalculating the same cost values over and over.
 
ok I cleaned up the code a little bit but its still basically the same as b4. The while loop i was talking about is the one in the main method. Also I chose to declare the variables at the class level to keep things simple that way i don't need any return statements. Check the previous post for the updated code (I just edited it)
 
To me, it doesn't look like your loop body ever even gets entered. Your invariant is:
Code:
while (line != null) {
but you allow line to be default initialized to null here:
Code:
    private static String ..., line, ...;
Your loop invariant really ought to look something like:
Code:
while ((line = input.readLine()) != null) {
which would allow you to get rid of the first line in tokenize().
 
Ive actually tried that but it gives me a nullpointerexception, here I'll change it and post what Im talking about.
 
Heres the code I got rid of the first line of tokenize and changed the while loop, but now when I try to run it I get a nullpointerexception error for the while loop line.
 
Code:
private static void readfile() throws IOException {
        FileReader studenttext = new FileReader("C:\\students.txt");
        BufferedReader input = new BufferedReader(studenttext);
}

You have a local variable hiding a field in this function. Try:
Code:
private static void readfile() throws IOException {
        FileReader studenttext = new FileReader("C:\\students.txt");
        input = new BufferedReader(studenttext);
}
 
Code:
private static void readfile() throws IOException {
        FileReader studenttext = new FileReader("C:\\students.txt");
        BufferedReader input = new BufferedReader(studenttext);
}

You have a local variable hiding a field in this function. Try:
Code:
private static void readfile() throws IOException {
        FileReader studenttext = new FileReader("C:\\students.txt");
        input = new BufferedReader(studenttext);
}

that did it! thank you, and thanks to everyone else as well
 
actually Ive got one more small issue, how would I make the filewriter always write the to the folder the .jar is in (\dist\). When I run the project on my usb drive it no longer saves the files.
 
You might find something in the properties methods in the System class.
im sorry but I guess I dont quite understand. so would I put system.getProperty(user.dir) some where in the file writer line? If so what part of that line corresponds to the directory path? Would user.dir even be the correct key? I need to make the files get saved in the same folder as the .jar once its built.
 
im sorry but I guess I dont quite understand. so would I put system.getProperty(user.dir) some where in the file writer line? If so what part of that line corresponds to the directory path? Would user.dir even be the correct key? I need to make the files get saved in the same folder as the .jar once its built.

Use a relative path.

Code:
import java.io.PrintWriter
....
PrintWriter out = new PrintWriter("test.txt");

This will create a file called test.txt in the directory where the jar was run from. You can substitute out the PrintWriter for a BufferedWriter decorating a FileWriter as you are doing above if you want, the concept is still the same.
 
Use a relative path.

Code:
import java.io.PrintWriter
....
PrintWriter out = new PrintWriter("test.txt");

This will create a file called test.txt in the directory where the jar was run from. You can substitute out the PrintWriter for a BufferedWriter decorating a FileWriter as you are doing above if you want, the concept is still the same.

but that would be how I already have it and right now it doesnt save to the .jar directory. So the program is on the USB drive and when I run it from inside netbeans it puts the files in my netbeans project folder. When I build the project and run the .jar from the command prompt it puts the files in my vista user folder (c:\users\joseph weaver).

heres a copy of my output method
 
but that would be how I already have it and right now it doesnt save to the .jar directory. So the program is on the USB drive and when I run it from inside netbeans it puts the files in my netbeans project folder. When I build the project and run the .jar from the command prompt it puts the files in my vista user folder (c:\users\joseph weaver).

Are you running it from that directory? What is the exact command line you are executing because your current directory you run the command from makes a difference. That being said you can use System.getProperty("user.dir") to get the users current working directory, however that command should reflect the default path FileWriter uses as well so I don't know how much that is going to help you. You can use System.getProperty("user.dir") as a place to start from while debugging.
 
im having trouble finding how to write the correct parameter to return the directory I need...
Just forget about it for now. Your code has bigger problems than this.

That being said you can use System.getProperty("user.dir") to get the users current working directory, however that command should reflect the default path FileWriter uses as well so I don't know how much that is going to help you.
No, user.dir isn't going to help at all. Thought the .jar might turn up in the classpath, however.
 
Yea I know my code needs alot of work, but I dont have time (due in less than 24hours) to go through and completely change my code. Right now the project meets all the assignment requirements and everything works except the location of where the files are written so this is what I need to focus on.
 
Just forget about it for now. Your code has bigger problems than this.


No, user.dir isn't going to help at all. Thought the .jar might turn up in the classpath, however.

I just tested the following code, FWIW

Standalone run from the command line using ">java Dirtest"

JAR from command line using ">java -jar Dirtest.jar"

and Double clicked from explorer, and in all cases it gave me the correct output

I even moved it to a usb drive and double clicked it, still gave me the right working directory.

Code:
public class Dirtest {

	public static void main(String args[]){
	    try{
	    	    System.out.println(System.getProperty("user.dir"));
		    Thread.sleep(10000);
	    }	
	    catch(InterruptedException e){
	        	e.printStackTrace();
	    }	
	}
}
 
I tried the following code and it sorta works, it puts the files on the usb drive, but in the root directory instead of the folder where the .jar is and it adds the directory to the name of the file which I do not want it to do.
 
It would help to know the relevant directory structure of your USB drive (i.e. where the JAR is relative to the root dir) and the exact method you're using to start your program (i.e. are you double-clicking the jar or running it from the command line). That said, I'm going to take a shot in the dark at something that might help you:
Code:
BufferedWriter output = new BufferedWriter(new FileWriter(
        System.getProperty("user.dir") [b]+ File.separator[/b] +
        lastname + " " + semester + ".txt"));
 
It would help to know the relevant directory structure of your USB drive (i.e. where the JAR is relative to the root dir) and the exact method you're using to start your program (i.e. are you double-clicking the jar or running it from the command line). That said, I'm going to take a shot in the dark at something that might help you:

The file path to the jar is G:\Joseph Weaver COP3804 HW 1\dist (G being the thumb drive). Heres my code which works perfectly when i run it from netbeans but gives me an error when I build it and run the .jar from the command line


heres the error

Code:
Exception in thread "main" java.io.FileNotFoundException: C:\Users\Joseph Weaver\dist\Perez fall 2008.txt (The system cannot find the path specified)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:70)
        at java.io.FileWriter.<init>(FileWriter.java:46)
        at homework1.Main.receipts(Main.java:37)
        at homework1.Main.main(Main.java:29)
Java Result: 1
 
From what directory are you running the program? "user.dir" will vary depending on what directory you're in on the command line when you invoke java.
 
Back
Top