Having a bit of trouble with file outputs and using try/catch. I'm trying to basically say that if the user inputs an existing filename, keep looping until valid filename is entered. However, i cant seem to get it to work. Any hints on where im going wrong? Tried moving the initial prompt around try block but wouldnt that make the scope only available in the try block? So essentially, i should have the prompt outside so its available to all the try/catch blocks? Not sure though.
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
public class TestAccountWithException
{
public static void main(String[] args) throws IOException
{
// variable declaration
String fileName;
String firstName;
String lastName;
double balance;
int id = 1122;
final double RATE = 4.50;
Scanner input = new Scanner(System.in);
System.out.print("Please enter file name: ");
fileName = input.next();
File fw = new File(fileName);
try
{
// check if file already exists
while(fw.exists())
{
System.out.print("File already exists. Enter valid file name: ");
fileName = input.next();
fw = new File(fileName);
}
System.out.print("Enter your first name: ");
firstName = input.next();
System.out.print("Enter your last name: ");
lastName = input.next();
System.out.print("Input beginnning balance: ");
balance = input.nextDouble();
// pass object to printwriter and use pw to write to the file
PrintWriter pw = new PrintWriter(fw);
// print to created file
pw.println(firstName);
pw.println(lastName);
pw.println(balance);
pw.println(id);
pw.println(RATE);
pw.close();
// System.out.print("Run program? (1) Yes (2) No: ");
// cont = input.nextInt();
} catch (IOException e) {
e.printStackTrace();
}
} // end main
} // end class
You may prefer to use java.nio.file. With this java 7 package, you can use as
while(true) {
String fileName = input.next();
Path path = Paths.get(fileName);
if (Files.exists(path)) {
try {
// file exists
// your operations
} catch {
}
break;
} else {
// not found
fileName = input.next();
}
}
Related
There are two files, one is userData.txt and the other one is gameData.txt. In my program, I give two options to the user. Login and Register. If the user clicks on the Register option, then I ask for the ID and password they'd like to keep and store them in userData.txt. Then I run a command which generates a random string which will be stored with the user's credentials in userData.txt as well as in the gameData.txt. After the unique token is written in gameData.txt, I will assign 0 coins as default. This is how it will look like:
Akshit, Joshi, 687fd7d1-b2a9-4e4a-bc35-a64ae8a25f5b (in userData.txt)
687fd7d1-b2a9-4e4a-bc35-a64ae8a25f5b, 0 (in gameData.txt)
Now, if a user clicks on Login option, then the program verifies the data from userData.txt. It also reads the unique token after the credentials and then stores it into a variable named uniUserID.
Now comes the part where I am stuck. I compare this uniUserID to the data in the gameData.txt file. The Scanner reads the gameData.txt line by line and compares the uniUserID with it. What I want is, if it finds the ID then it should read the coins after it (which is 0) and store it into a variable named coins. But it throws me an error that goes like, "NoSuchElementException"
Here is the code:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.Scanner;
import java.util.UUID;
public class Verification
{
static File credentials = new File ("C:\\Users\\user\\IdeaProjects\\Economic Bot\\out\\userData.txt"); //Clarifying filepath
static String uniUserID = " ";
static File gameData = new File ("C:\\Users\\user\\IdeaProjects\\Economic Bot\\out\\gameData.txt");
public boolean Verify (String ID,String Pass)
{
String tempName = " "; //the data read from the .txt file would be stored in these temporary variables
String tempPass = " ";
boolean found = false;//declaring some boolean variables so that the do while and if else statements work smoothly
boolean verified = false;
try //Try and catch block is initialized in case the file is not found
{
do
{
Scanner s2 = new Scanner(credentials); //Reading the .txt file
s2.useDelimiter("[,\n]");// The file reader will stop once it encounters any of the following delimiters
while (s2.hasNext() && !found)
{
tempName = s2.next(); //assigning the data read from the file to these variables
tempPass = s2.next();
uniUserID= s2.next();
if (tempName.trim().equals(ID) && tempPass.trim().equals(Pass))//comparing the data read from the file and the data entered by the user
{
verified = true;
found = true;
}
}
}
while (found = false);
}
catch (Exception ex)
{
System.out.println("Error");
}
return verified;
}
public void Write (String newUser, String newPass) {
String uniID = " ";
try {// try catch is used in case the file is not found
uniID = UUID.randomUUID().toString();
FileWriter writer = new FileWriter(credentials, true);// initializing the FileWriter, to make sure that it doesn't overwrite true is used so that it appends
BufferedWriter buffwrite = new BufferedWriter(writer); // creating buffered writer object
buffwrite.write("\n"); // Writing the new user's credentials into the .txt file
buffwrite.write(newUser);
buffwrite.write(",");
buffwrite.write(newPass);
buffwrite.write(",");
buffwrite.write(uniID);
buffwrite.close();
} catch (Exception ex) {
System.out.println("Error");
}
try
{
FileWriter writer2 = new FileWriter(gameData, true);
BufferedWriter buffwrite2 = new BufferedWriter(writer2);
buffwrite2.write("\n");
buffwrite2.write(uniID);
buffwrite2.write(",");
buffwrite2.write("0");
buffwrite2.close();
}
catch(Exception ex)
{
System.out.println("Error");
}
}
public static void Game(String uniqueID) throws FileNotFoundException
{
Scanner s3 = new Scanner (gameData);
String waste = " ";
String coins = " ";
while (s3.hasNextLine())
{
String fileLine = s3.nextLine();
if(fileLine.contains(uniUserID))
{
s3.useDelimiter(("[\n]"));
s3.skip(uniUserID);
coins = s3.next();
}
}
System.out.println(coins);
}
public static void main(String[] args) throws FileNotFoundException {
Verification obj = new Verification();
Scanner s1 = new Scanner(System.in); //Creating scanner object
boolean end = false; //declaring the variable that will end the do while loop
do //do while loop is used so that the user gets taken to the main menu again and again
{
System.out.println("Welcome to the economic bot!");
System.out.println("Select one option to proceed");
System.out.println("1. Login");
System.out.println("2. Register");
int choice = s1.nextInt(); //accepting user's choice
switch (choice) {
case 1:
System.out.println("Enter your username:");
String userID = s1.next(); //taking user credentials
System.out.println("Enter your password");
String userPass = s1.next();
boolean validated = obj.Verify(userID,userPass);
if (validated == true) { //if the login details are correct
System.out.println("Login Successful!");
System.out.println("Redirecting...");
System.out.println();
end = true;
Game(uniUserID);
}
else { //if the details entered are wrong
System.out.println("Login failed! Possibly due to wrong user credentials.");
System.out.println("Please try again!");
}
break;
case 2:
System.out.println("Enter the username you'd like to keep:");
String regUserID = s1.next(); //accepting user details
System.out.println("Enter the password:");
String regUserPass = s1.next();
obj.Write(regUserID,regUserPass);
break;
default:
System.out.println("Invalid Option chosen."); // In case the user enters a wrong choice
}
}
while (!end); // condition for the initial do loop
}
}
Try the below code :
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.Scanner;
import java.util.UUID;
public class Verification {
static File credentials = new File("C:\\Users\\user\\IdeaProjects\\Economic Bot\\out\\userData.txt"); //Clarifying filepath
static String uniUserID = " ";
static File gameData = new File("C:\\Users\\user\\IdeaProjects\\Economic Bot\\out\\gameData.txt");
public boolean Verify(String ID, String Pass) {
String tempName = " "; //the data read from the .txt file would be stored in these temporary variables
String tempPass = " ";
boolean found = false;//declaring some boolean variables so that the do while and if else statements work smoothly
boolean verified = false;
try //Try and catch block is initialized in case the file is not found
{
do {
Scanner s2 = new Scanner(credentials); //Reading the .txt file
s2.useDelimiter("[,\n]");// The file reader will stop once it encounters any of the following delimiters
while (s2.hasNext() && !found) {
tempName = s2.next(); //assigning the data read from the file to these variables
tempPass = s2.next();
uniUserID = s2.next();
if (tempName.trim().equals(ID) && tempPass.trim().equals(Pass))//comparing the data read from the file and the data entered by the user
{
verified = true;
found = true;
}
}
}
while (found = false);
} catch (Exception ex) {
System.out.println("Error");
}
return verified;
}
public void Write(String newUser, String newPass) {
String uniID = " ";
try {// try catch is used in case the file is not found
uniID = UUID.randomUUID().toString();
FileWriter writer = new FileWriter(credentials, true);// initializing the FileWriter, to make sure that it doesn't overwrite true is used so that it appends
BufferedWriter buffwrite = new BufferedWriter(writer); // creating buffered writer object
buffwrite.write("\n"); // Writing the new user's credentials into the .txt file
buffwrite.write(newUser);
buffwrite.write(",");
buffwrite.write(newPass);
buffwrite.write(",");
buffwrite.write(uniID);
buffwrite.close();
} catch (Exception ex) {
System.out.println("Error");
}
try {
FileWriter writer2 = new FileWriter(gameData, true);
BufferedWriter buffwrite2 = new BufferedWriter(writer2);
buffwrite2.write("\n");
buffwrite2.write(uniID);
buffwrite2.write(",");
buffwrite2.write("0");
buffwrite2.close();
} catch (Exception ex) {
System.out.println("Error");
}
}
public static void Game(String uniqueID) throws FileNotFoundException {
Scanner s3 = new Scanner(gameData);
String waste = " ";
String coins = " ";
while (s3.hasNextLine()) {
String fileLine = s3.nextLine();
if (fileLine.contains(uniUserID)) {
/*s3.useDelimiter(("[\n]"));
s3.skip(uniUserID);
coins = s3.next();*/
coins = fileLine.split(",")[1];
break;
}
}
System.out.println(coins);
}
public static void main(String[] args) throws FileNotFoundException {
Verification obj = new Verification();
Scanner s1 = new Scanner(System.in); //Creating scanner object
boolean end = false; //declaring the variable that will end the do while loop
do //do while loop is used so that the user gets taken to the main menu again and again
{
System.out.println("Welcome to the economic bot!");
System.out.println("Select one option to proceed");
System.out.println("1. Login");
System.out.println("2. Register");
int choice = s1.nextInt(); //accepting user's choice
switch (choice) {
case 1:
System.out.println("Enter your username:");
String userID = s1.next(); //taking user credentials
System.out.println("Enter your password");
String userPass = s1.next();
boolean validated = obj.Verify(userID, userPass);
if (validated == true) { //if the login details are correct
System.out.println("Login Successful!");
System.out.println("Redirecting...");
System.out.println();
end = true;
Game(uniUserID);
} else { //if the details entered are wrong
System.out.println("Login failed! Possibly due to wrong user credentials.");
System.out.println("Please try again!");
}
break;
case 2:
System.out.println("Enter the username you'd like to keep:");
String regUserID = s1.next(); //accepting user details
System.out.println("Enter the password:");
String regUserPass = s1.next();
obj.Write(regUserID, regUserPass);
break;
default:
System.out.println("Invalid Option chosen."); // In case the user enters a wrong choice
}
}
while (!end); // condition for the initial do loop
}
}
Suggestions:
Try adding a new line (\n) character at the end of every line not at the beginning because it is adding a blank line at the start of the files.
Break the loop if the id matching is found.
Change the Game() method to this:
{
Scanner s3 = new Scanner (gameData);
String waste = " ";
String coins = " ";
while (s3.hasNextLine())
{
String fileLine = s3.nextLine();
if(fileLine.contains(uniUserID))
{
coins = fileLine.split(",")[1];
break;
}
}
System.out.println(coins);
}
Simply split the line in 2 parts using a divider (,) and get the second part where are contained the coins
To add more coins, use a BufferedWriter:
BufferedWriter writer = new BufferedWriter(new FileWriter(gameData));
writer.write(uniId+","+newCoins);
writer.close();
Important: remove true from the FileWriter object because you are overwriting and not appending
This program is supposed to take in user input about a players name, assists, games played, scores, etc and print it in a .txt file. When the updateData(); method is called I want to be able to ask the user for the players name and what data they want to update, then i should be able to edit that specific part of the text. how could i go about doing this?
Main Class
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
public class TextReader {
public static void main(String[] args) throws IOException {
Path path = Paths.get("/Users/Coding/Desktop/myFile.txt").toAbsolutePath();
try (Scanner scan = new Scanner(System.in);
BufferedReader fileReader = new BufferedReader(new FileReader(String.valueOf(path)));
BufferedWriter fileWriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) {
Reader reader = new Reader(scan, path, fileWriter, fileReader);
reader.menu();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Reader Class
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
public class Reader {
Path path;
Scanner scan;
BufferedWriter fileWriter;
BufferedReader fileReader;
Reader(Scanner scan, Path path, BufferedWriter fileWriter, BufferedReader fileReader) {
this.scan = scan;
this.path = path;
this.fileWriter = fileWriter;
this.fileReader = fileReader;
}
public void menu() throws IOException {
String task;
do{
System.out.print("What would you like to do today?: ");
task = scan.nextLine();
switch (task) {
case "1":
addData();
break;
case "2":
updateData();
break;
case "6":
System.out.println("Goodbye!");
System.exit(0);
}
}while(!task.equals("6"));
}
void addData() throws IOException {
boolean cont;
DateTimeFormatter log = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime time = LocalDateTime.now();
String logTime = log.format(time);
do try {
System.out.print("Enter Name of Player: ");
String playerName = scan.nextLine();
System.out.print("Enter Number of Games Played: ");
int gamesPlayed = Integer.parseInt(scan.nextLine());
System.out.print("Enter Number of Goals Made: ");
int goals = Integer.parseInt(scan.nextLine());
System.out.print("Enter Number of Assists Made: ");
int assists = Integer.parseInt(scan.nextLine());
System.out.print("Enter Number of Points Scored: ");
int points = Integer.parseInt(scan.nextLine());
System.out.print("Enter Number of Saves Made: ");
int saves = Integer.parseInt(scan.nextLine());
System.out.print("Enter Number of Shots Made: ");
int shotsOnGoal = Integer.parseInt(scan.nextLine());
fileWriter.write(
playerName + " " + gamesPlayed + " " + goals + " " +
assists + " " + points + " " + saves + " " + shotsOnGoal + " (" + logTime + ") \n");
cont = false;
} catch(NumberFormatException e){
System.out.println("Enter Valid Input");
cont = true;
}while(cont);
}
void updateData() throws IOException {
System.out.print("Enter Player Name To Edit Data: ");
String playerName = scan.nextLine();
System.out.print("Enter Stat You Want To Change: ");
String stat = scan.nextLine().toLowerCase().trim();
if(fileReader.readLine().contains(playerName)){
String statSearch = fileReader.readLine();
}
}
}
}
Text File Format:
Name GP G A P S S%
Bobby 2 3 6 14 7 50
George 1 3 14 2 9 23
So if the user wanted to edit Name: George, type: Assists, the value 14 beside Georges name only would be edited
I have tried using an if statement to locate the string in the text and append it but I could not figure out how to only change the specified number without changing all the numbers found. Ex: if in the example above 14 is appended both would be changed instead of the one
If you are allowed for this project (i.e., not a school assignment), I recommend using JSON, YAML, or XML. There are too many Java libraries to recommend for using these types of files, but you can search "Java JSON library" for example.
First, need to address some issues...
It's not good practice to put Scanner scan = new Scanner(System.in); in a try-with-resource. It will auto-close System.in and won't be useable after being used in your Reader class. Instead, just do this:
Scanner scan = new Scanner(System.in);
Reader reader = new Reader(scan, path, fileWriter, fileReader);
Or, even better, don't pass it to the constructor, but just set scan to it in the constructor as this.scan = new Scanner(System.in);
Next, for fileReader, you can just initialize it similarly as you did for fileWriter:
BufferedReader fileReader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
Next, this line:
BufferedWriter fileWriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8)
Every time this program is run, this line will overwrite the file to empty, which is probably not what you want. You could add StandardOpenOption.APPEND, but then this means you'll only write to the end of the file.
When you update data, you also have the issue that you'll need to "push" down all of the data that comes after it. For example:
Bobby 1 2 3 4 5
Fred 1 2 3 4 5
If you change the name Bobby to something longer like Mr. President, then it will overwrite the data after it.
While there are different options, the best and simplest is to just read the entire file and store each bit of data in a class (name, scores, etc.) and then close the fileReader.
Then when a user updates some data, change that data (instance variables) in the class and then write all of that data to the file.
Here's some pseudo-code:
class MyProg {
// This could be a Map/HashMap instead.
// See updateData().
public List<Player> players = new ArrayList<>();
public void readData(String filename) throws IOException {
Path path = Paths.get(filename);
try(BufferedReader fileReader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
// Read each Player (using specific format)
// and store in this.players
}
}
public void writeData(String filename) throws IOException {
Path path = Paths.get(filename);
try(BufferedWriter fileWriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) {
// Write each Player from this.players in specific format
}
}
public void updateData() {
// 1. Find user-requested Player from this.players
// 2. Update that specific Player class
// 3. Call writeData()
// If you are familiar with Maps, then it would be faster
// to use a Map/HashMap with the key being the player's name.
}
}
class Player {
public String name;
public int games;
public int goals;
//...
}
EDIT: I ADDED A NEW PART to catch fileexception error
This is a pincheck program. I'm supposed to create a txt file with the following lines:
peter, 1212
john, 1234
mary, 0000
I then have to write a java program to prompt user for the file path of the txt file then key in their name and pin number. I'm able to compile my code but I don’t get the expected result when I type in the correct name and pin.
import java.util.*;
import java.io.*;
public class PINCheck {
public static void main(String[]args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter file path: ");
String filepath = s.nextLine();
File passwordFile = new File(filepath);
System.out.print("Enter name: ");
String name = s.nextLine();
System.out.print("Enter password: ");
String password = s.nextLine();
try {
Scanner sc = new Scanner(passwordFile);
while (sc.hasNext()) {
if (password.matches(".*[a-zA-Z]+.*")) {
System.out.println("You have entered a non-numerical PIN!");
} else if (sc.hasNext(name) && sc.hasNext(password)) {
System.out.println("You have logged in successfully.");
}else {
System.out.println("Login Failed.");
}
break;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
This line : Scanner sc = new Scanner("passwordFile"); implies that Scanner will scan from the String specified in the constructor and not the actual file.
Use Scanner sc = new Scanner(passwordFile); instead.
A similar mistake for File passwordFile = new File("filepath");.
Use it like File passwordFile = new File(filepath);
In both cases, pass the variable, not the string.
import java.io.*;
import java.util.*;
import java.lang.*;
public class FileWritingApp{
public static void main(String[] args) {
String inputFilename = "marks.txt"; // It expects to find this file in the same folder as the source code
String outputFilename = "fakemarks.txt"; // The program will create this file
PrintWriter outFile;
String name,choice;
int mark1,mark2;
boolean flag=false;
Scanner input = new Scanner(System.in);
System.out.println("Do you want to add or find a student?");
try {
outFile = new PrintWriter(new FileWriter(outputFilename),true); // create a new file object to write to
File file = new File(inputFilename); // create a file object to read from
File file1 = new File(outputFilename);
Scanner scanner = new Scanner(file); // A scanner object which will read the data from the file passed in.
choice= input.nextLine();
switch(choice){
case "f":
System.out.println("Enter a name:");
name=input.nextLine();
while (scanner.hasNextLine()) { // This will loop until there are no more lines to read
String line = scanner.nextLine();
if(line.contains(name)){
System.out.println("Enter the first mark set:");
mark1=input.nextInt();
System.out.println("Enter the second mark set:");
mark2=input.nextInt();
line=name+", " + mark1 +", "+ mark2;
outFile.println(line);
flag=true;
} else {
outFile.println(line);
}
}
if(flag==false){
System.out.println('"'+name+'"'+" wasn't found");
}
break;
case "a":
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
outFile.println(line);
}
System.out.println("Enter a name:");
name=input.nextLine();
System.out.println("Enter the first mark set:");
mark1=input.nextInt();
System.out.println("Enter the second mark set:");
mark2=input.nextInt();
outFile.println(name+", " + mark1 +", "+ mark2);
break;
}
***scanner.close();
outFile.close();
if(file1.renameTo(file)){
System.out.println("rename succesful");
} else {
System.out.println("rename unsuccesful");
}
if(file.delete()){
System.out.println("delete succesful");
} else {
System.out.println("delete unsuccesful");
}***
}catch (IOException e) {
e.printStackTrace();
}
}
}
What I am having a problem with is that every time I run the program it returns false for changing the name of the new file to the original file and deleting the original file itself. I would appreciate if someone posted some code to solve this. I have highlighted the code that outputs feedback above.
the following is my sources code:
package functiontest;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class FunctionTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int option;
String cname, cpassword="testpassword",chp="010-000000";
// cname="clerk test";
System.out.println("1. add");
System.out.println("2. delete");
option = scan.nextInt();
switch(option)
{
case 1:
System.out.print("Enter clerk name:\t");
cname = scan.nextLine();
File cfile = new File("clerk/"+cname+".txt");
FileWriter cwrite;
try
{
cwrite = new FileWriter(cfile);
BufferedWriter cbuf = new BufferedWriter(cwrite);
cbuf.write("clerk name:\t" +cname);
cbuf.write("clerk password:\t"+cpassword);
cbuf.write("clerk handphone number:\t"+chp);
cbuf.flush();
cbuf.close();
System.out.println("The clerk profile create completely");
}catch(IOException e)
{
System.out.println("Error! clerk profile cannot create");
}
;break;
case 2:
String dclerk;
// dclerk = "clerk test";
System.out.print("\nPlease enter clerk name for delete:\t");
dclerk = scan.next();
File dcfile = new File("clerk/"+dclerk+".txt");
if(!dcfile.exists())
{
System.out.println("Error! the clerk profile not exist");
}
try
{
dcfile.delete();
System.out.println(dclerk + "'s prifle successful delete");
}catch(Exception e)
{
System.out.println("Something wrong! " + dclerk +" profile cannot delete");
};break;
}
}
}
i cannot the enter the variable name cname
cname = scan.nextLine()
when i run the program it show the result as below:
run:
1. add
2. delete
1
Enter clerk name: The clerk profile create completely
when i use .next():
cname = scan.next()
it cannot read the
cname
with spaces, example
clerk test
it will read
clerk
only how should i do?
Your problem is that the line
option = scan.nextInt();
does not read the new line character after the integer. So that new line is finally read when you do nextLine(), later on.
To fix this, you should add an extra
scan.nextLine()
after the call to nextInt(), then use
cname = scan.nextLine();
when you want to read the clerk's name.