I have an assignment where I need to write a while loop code block that contains a trycatch statement. The try block retrieves each line from an input file, and invokes an isValid method I created to check if the format is correct, passing to it the line from the file. If there are no more lines to parse, runProgram is set to false, the while loop terminates. The catch block will catch an exception that I made. So far I have
public static void main(String[] args)
{
File file;
Scanner inputFile;
String fileName;
Scanner scan = new Scanner(file);
fileName = scan.nextLine();
boolean runProgram = true;
while(runProgram)
{
try
{
// for loop to check each line of my file
// invoke isValid
// Check if it's the last line in the file, and end program if so
}
catch(BankAccountException e)
{
System.out.println("Account Exception. Do you wish to quit? y/n");
String quit = scan.nextLine();
if(quit.equals("y"))
runProgram = false;
else
runProgram = true;
}
}
}
I just have no idea how to open a file, check the next line, use my isValid method (which is just a StringTokenizer that checks for the correct format), and closes when it reaches the end of the file.
Here is my isValid method:
private static boolean isValid(String accountLine) throws BankAccountException
{
StringTokenizer strTok = new StringTokenizer(accountLine, ";");
boolean valid = true;
if(strTok.countTokens() == 2)
{
if(strTok.nextToken().length() == 10)
{
if(!strTok.nextToken().matches(".*[0-9].*"))
{
valid = true;
}
}
}
else
valid = false;
return valid;
}
I also have a question with the above method. If I call .nextToken() twice, am I right in expecting the first iteration to deal with the first token, and the second to deal with the second? Or will they both just check the first token?
Just to get you started.
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("/path/to/File")));
String currLine;
while ((currLine = reader.readLine()) != null) { // returns null at EOF
if (!isValid(currLine)) throw new BankAccountException();
}
} catch (BankAccountException e) {
// same
} finally {
reader.close();
}
Related
I'm making a user system in Java using text files and i'm trying to make it so that the same username can't register twice. It completely ignores it and allows for the creation anyway.
The code I have below is:
static boolean checkUsername(String u) { //Check the username and password
boolean userFound = false;
try { //Try and read our user file
Scanner loginRead = new Scanner(loginFile); //Load the file into the scanner
loginRead.useDelimiter("|"); //Split each set of user data into an array with |
try {
if(loginRead.nextLine() ==null) {
return false;
} else {
while(loginRead.nextLine() !=null){ //Run line by line until we find this MF
String user_r = loginRead.next(); //loginRead[0] = Username
loginRead.next(); //Read the line
if(u.equals(user_r)){ //If we have a match
userFound=true;
break; //Break the login script because we've struck gold
}
}
}
} catch(NoSuchElementException e) {
return false;
}
} catch (FileNotFoundException exceptionText) { //We couldn't find the user file.
System.out.println("User file error");
}
return ((userFound==true) ? true : false); //Short hand if statement
//to tell us if we found that user
}
User file:
username|pwhash|fname|lname
username|pwhash|fname|lname
username|pwhash|fname|lname
username|pwhash|fname|lname
Where am I going wrong?
Very, very late. But I re-did the code and here is what I went with, for anyone else wondering:
static boolean checkUsername(String u) throws IOException { //We use this function when registering a user, to make sure they don't already exist
boolean userFound = false; //Our boolean for if the user exists
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("./loginData.dat")); //Load our loginData.dat file into the buffer
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (String line = br.readLine(); line != null; line = br.readLine()) { //Read the file line by line
String[] userDataNew=line.toString().split("\\|"); //Split our line up into an array using |
if(userDataNew[0].equals(u)) { //We've found their username already
userFound = true; //Set our user found bool to true
break; //Break out of the foor loop
}
}
return userFound; //Return true/false
}
I'm writing an application that is supposed to act like a cafe clip card. In other words, for every n:th (10 in my case) coffee that a customer purchases, he/she is awarded a free beverage. So, I'm quite done with the loop and I've been working on writing and reading from a file since I need the program to remember where it last left off in order for the customer to be able to close the application once he/she has been in the store. However, I'm having a difficult time figuring out how to write and read from a file, the code I have doesn't seem to output any .txt file. I need the code to have a closing condition, and upon entering this condition, it should write the "count" to a .txt file, and shut down. Once the program is being run the next time it should read from this .txt file so it knows where the count is at.
Here's what I have so far:
public class FelixNeww {
public static void main(String [] args) {
Scanner key;
String entry;
int count = 0;
String password = "knusan01";
while(true) {
System.out.println("Enter password: ");
key = new Scanner(System.in);
entry = key.nextLine();
if(entry.compareTo(password) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought "
+ count + " coffe(s)");
}
if(count == 10 && count != 0){
System.out.println("YOU'VE GOT A FREE COFFE!");
count = 0;
}
if(entry.compareTo(password) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
}
public void saveToFile(int count)
{
BufferedWriter bw = null;
try
{
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("countStorage.txt"))));
bw.write(count);
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(bw != null)
{
try
{
bw.close();
}
catch(IOException e) {}
}
}
}
public int readFromFile()
{
BufferedReader br = null;
try
{
br = new BufferedReader(newInputStreamReader(newFileInputStream(new File("countStorage.txt"))));
String line = br.readLine();
int count = Integer.parseInt(line);
return count;
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(br != null)
{
try
{
br.close();
}
catch(IOException e) {}
}
}
return 0;
}
}
I see a few problems here. In your readFromFile() method, put a space after the keyword new. I also suggest putting a an absolute path for now (for debugging):
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Temp\\countStorage.txt"))));
In your saveToFile() method, the constructor is wrong. Also put the full path to the file here:
bw = new BufferedWriter(new FileWriter("C:\\Temp\\countStorage.txt"));
Finally, in your saveToFile() method, write the count as a String. Writing it as an int refers to the Unicode character:
bw.write(Integer.toString(count)); //updated per Hunter McMillen
And invoke it...
FelixNeww f = new FelixNeww();
f.saveToFile(44);
System.out.println(f.readFromFile());
You need to invoke readFromFile or saveToFile in the place needed in order to become executed.
I suggest that you call readFromFile on the beginning of the Main method, use its returning contents, and saveToFile in the loop whenever the desired state changes and it needs to be saved.
I have been working on this code for the day and am almost at the finish line. What I want is that the code should work as a clip card, remembering the number of purchased coffees, and awarding the customer a free coffee every 10th purchase. I'm writing to a file and reading from it in order for a customer to be able to continue his clip card where he left of last time. So to my problem...I have properly been able to write my "count" variable to a file, and it is storing it correctly. However, every time I run the program again it starts off a 0 and I don't see why. I need it to save the current count, and read the count once run again. For example, if a customer has previously purchased 7 coffees and is returning to the store, his counter needs to start at 7. For some reason it is not doing that.
Here's what I have so far:
public class FelixNeww {
public static void main(String [] args) {
Scanner key;
String entry;
int count = 0;
String password = "knusan01";
FelixNeww f = new FelixNeww();
System.out.println(f.readFromFile());
while(true) {
System.out.println("Enter password: ");
key = new Scanner(System.in);
entry = key.nextLine();
if(entry.compareTo(password) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought "
+ count + " coffe(s)");
f.saveToFile(count);
}
if(count == 10 && count != 0){
System.out.println("YOU'VE GOT A FREE COFFE!");
count = 0;
}
if(entry.compareTo(password) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
}
public void saveToFile(int count)
{
BufferedWriter bw = null;
try
{
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("C:\\Temp\\countStorage.txt"))));
bw.write(Integer.toString(count));
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(bw != null)
{
try
{
bw.close();
}
catch(IOException e) {}
}
}
}
public int readFromFile()
{
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Temp\\countStorage.txt"))));
String line = br.readLine();
int count = Integer.parseInt(line);
return count;
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(br != null)
{
try
{
br.close();
}
catch(IOException e) {}
}
}
return 0;
}
}
You are currently setting your count variable to 0. You should set it to the value that's in the file. Do this just before the while loop:
count = f.readFromFile();
while(true) {
You should also implement a way to gracefully exit the while loop. For example, if the user enters "q", you can execute the break; statement to exit the while loop. And after your while loop, call key.close(); to close the Scanner object.
The scope of count variable is local in both instances
public static void main(String [] args) {
Scanner key;
String entry;
int count = 0;
String password = "knusan01";
System.out.println(f.readFromFile());
public int readFromFile()
{
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Temp\\countStorage.txt"))));
String line = br.readLine();
int count = Integer.parseInt(line);
return count;
In the readFromFile function, you read it from the file, return it, but don't keep track of it in a variable, why don't you replace the println with this inside your main:
count=f.readFromFile
I'm tinkering around on a small application to read some numbers in from a file. Everything runs well so far, but now I have encountered a problem I don't know how I can effectively fix it. If the user enters, unintentionally maybe, the wrong filename a FileNotFoundException will be thrown by the JVM, that I catch in my invoking method. Now I want to give him (the user) two another tries to enter the correct filename, but I don't know how I can invoke the method again which is opening the file when I'm actually in the catch-block below.
I will illustrate my transient solution below, but I'm not really sure if this is the most effective/elegant way to solve this problem:
//code omitted
int temp = 0;
while(true) {
filename = input.next();
try {
ex.fileOpen(filename);
}
catch(FileNotFoundException e) {
if(temp++ == 3) {
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
continue;
}
break;
}
//do some other stuff
input is a scanner which reads the user input and assigns it to the String-variable filename. fileOpen is a method which takes a filename, opens the file, reads the content and write all numbers in a vector.
So, I would really appreciate every support from the more experienced java programmers.
Greetings
Tom
You could use something like this,
public class AppMain {
public static void main(String[] args) throws IOException {
String filePath = input.next();
InputStream is = getInputStream(filePath);
int temp = 0;
while(is == null && temp < 3){
filePath = input.next();
is = getInputStream(filePath);
temp++;
}
if(is == null){
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
.........
.........
}
private static InputStream getInputStream(String filePath){
InputStream is = null;
try{
is = new FileInputStream(filePath);
return is;
}catch (IOException ioException) {
return null;
}
}
}
You may want to recursively call the method again:
public void doTheStuff(int attemptsLeft)
// ...
if (attemptsLeft == 0) {
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
filename = input.next();
try {
ex.fileOpen(filename);
}
catch(FileNotFoundException e) {
doTheStuff(attemptsLeft - 1);
return;
}
// ...
}
then simply call doTheStuff(3)
You can use exists method of the File class
For example fileOpen method can return true/false whether file exists
Think this will work.
int x = 0;
while (true){
filename = input.next();
try{
ex.fileOpen(filename);
break; // If it throws an exeption, will miss the break
}catch(FileNotFoundException e){
System.err.println("File not found, try again.");
}
if (x==2){
System.errprintln("You have entered the wrong file 3 times");
System.exit(0);
}
x++
}
Do not use exceptions to control your WorkFlow. Try something like this:
final int MAX_ERROR_ALLOWED=3;
public void readFile(String filename, int errorCount){
try{
File f = new File(filename);
if(!f.exists()){
String newFilename = input.next();
if(errorCount>=MAX_ERROR_ALLOWED){
throw new JustMyException();
}
readFile(newFilename, errorCount++);
}else{
//whatever you need to do with your file
}
}
}
How about something like this (pseudocode, not executable)?
// ...
for(int i = 0; i < 3; i++)
{
// User interaction to get the filename
if(attemptToOpenFile(ex))
{
break;
}
}
// Check if the file is open here and handle appropriately.
// ...
}
bool attemptToOpenFile(File ex, String filename) { // Forgot the class name for this
try {
ex.fileOpen(filename);
return true;
} catch(FileNotFoundException e) {
return false;
}
}
Alternatively, check if the file exists before calling fileOpen().
Struggling still with this after hours or research.. I have a simple helper class which is my first foray into try/catch error handling. I want to know if an input is valid against the type required and ask for a new input if it isn't... simple or so I thought. The class is being used in a simple term deposit calculator and is called multiple times (i.e. initial deposit, interest rate etc).
Here is the offending class, if this isn't sufficient to resolve I'll post up some additional snippets.
private Float inFloat;
private String temp;
private int inInt;
private String inString;
BufferedReader in = null;
boolean validInput = false;
public Float getFloat(String prompt) {
validInput = false;
do {
try {
in = new BufferedReader(new InputStreamReader(System.in));
System.out.print(prompt);
temp = in.readLine();
inFloat = Float.valueOf(temp);
validInput = true;
} catch (IOException e) {
System.out.println("Please enter a valid float value");
} finally {
try {
if (in != null) {
in.close();
}
} catch(IOException e) {
e.printStackTrace();
}
}
} while (validInput == false);
return inFloat;
}
Update - Fixed!!!
Thanks for the quick feedback... I managed to find another post that mentioned I shouldn't be closing off the BufferedReader and came up with the following adjustments so it now works. I'm now catching a NumberFormatException as well.. thanks for the tip :)
Not sure why it works now that I don't close off the BufferedReader... but I'll take the result!!
private Float inFloat;
private String temp;
private int inInt;
private String inString;
BufferedReader in = null;
boolean validInput = false;
public Float getFloat(String prompt) {
validInput = false;
do {
try {
in = new BufferedReader(new InputStreamReader(System.in));
System.out.print(prompt);
temp = in.readLine();
inFloat = Float.valueOf(temp);
validInput = true;
} catch (NumberFormatException e) {
System.out.println("Please enter a valid float value");
} catch (IOException e) {
e.printStackTrace();
}
} while (validInput == false);
return inFloat;
}
Float.valueOf(String s) will throw a NumberFormatException if it can't parse the input. Catch that one in addition to IOException.
In your code, NumberFormatException is thrown (if the input is invalid) but not catched inside the method, so the method will return immediatly after completing the finally block.