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;
//...
}
Related
My apologies for the title wording, it was hard to explain in words.
What I am trying to do I this:
I have a .txt file that has
cheese cracker salt
bread butter ham
I want the user to be able to enter 'cheese' then type in pepper which will in turn update the file to become
cheese cracker pepper
bread butter ham
I am unsure how to go about editing the third word after I have the user input the first word.
Your algorithm could look like this:
read in the file
split it up by spaces (you will get an array)
put the result into a modifiable list (you can't easily insert into an array)
search for the index of a word
insert another entry by index (you can calculate the correct index from the result of step 4)
overwrite the file with the contents of the list, separated by additional spaces.
Here is a solution utilizing File module along with BufferedReader/BufferedWriter
packages
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;
import java.nio.file.*;
Driver program
public class Main{
public static void main(String[] args) throws IOException{
Scanner sc = new Scanner(System.in);
System.out.println("Enter the file name: ");
String path = sc.nextLine();
Path p = Paths.get(path);
List <String> lines = Files.readAllLines(p);
System.out.println("Enter new word:");
String newWord = sc.nextLine();
System.out.println("Which word would you like " + newWord + " to replace?");
String oldWord = sc.nextLine();
for(int i = 0; i < lines.size(); i++){
String line = lines.get(i);
line = line.replace(oldWord, word); // if current word is old word, replace with new one
lines.set(i, line); // update list
}
readFile(path); // read here will output original list
writeListToFile(lines, path); // overwrite sample.txt file
readFile(path); // read here will output updated text file from path
sc.close();
}
helper functions
public static void readFile(String fileName){
try{
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
while(line != null){
System.out.println(line);
line = br.readLine();
}
br.close();
}catch(IOException e){
System.out.println("Error reading file");
}
}
public static void writeListToFile(List<String> list, String path){
try{
FileWriter fw = new FileWriter(path);
BufferedWriter bw = new BufferedWriter(fw);
for(int i = 0; i < list.size(); i++){
bw.write(list.get(i));
bw.newLine();
}
bw.close();
}catch(IOException e){
System.out.println("Error writing to file");
}
}
}
I am writing a program that lets the user enter up to 9999 accounts into a text file, however the issue i'm having is that they can be put in any order, but I have to print them in a sequential order. Here's my code
import java.nio.file.*;
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
import static java.nio.file.StandardOpenOption.*;
import java.util.Scanner;
import java.text.*;
public class CreateBankFile {
public static int lines = 0;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Path file = Paths.get("/root/sandbox/BankAccounts.txt");
String line = "";
int acctNum = 0;
String lastName;
double bal;
final int QUIT = 9999;
try
{
OutputStream output = new BufferedOutputStream(Files.newOutputStream(file));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
while(acctNum != QUIT)
{
System.out.print("Enter the acct num less than 9999: ");
acctNum = input.nextInt();
if(acctNum == QUIT)
{
continue;
}
System.out.print("Enter a last name: ");
lastName = input.next();
if(lastName.length() != 8)
{
if(lastName.length() > 8)
{
lastName = lastName.substring(0, 8);
}
else if(lastName.length() < 8)
{
int diff = 8 - lastName.length();
for(int i = 0; i < diff; i++)
{
lastName += " ";
}
}
}
System.out.print("Enter balance: ");
bal = input.nextDouble();
line = "ID#" + acctNum + " " + lastName + "$" + bal;
writer.write(line);
writer.newLine();
lines++;
}
writer.close();
}
catch(IOException e)
{
System.out.println("Error");
}
}
}
My question being, how can I get it so that when the user inputs "55" for example, it is printed to the 55th line of the text file?
You can do something like this :
1) create a class that will store your line ( acctNum , lastName .. etc )
2) in your method , create an arraylist of the class you created , for a given number "n" , your method will parse all the lines , if acctNum is less than "n" , you will create a new instance using this line and add it to your arraylist
3) you will sort the arraylist using the acctNum and then print its content
Perhaps FileChannels would work for you:
RandomAccessFile writer = new RandomAccessFile(file, "rw");
FileChannel channel = writer.getChannel();
ByteBuffer buff = ByteBuffer.wrap("Test write".getBytes(StandardCharsets.UTF_8));
channel.write(buff,5);//5 is the distance in the file
Lots of good examples on the web.
In your question I think you are taking acctNum as line number and you want to add a line at this line number in the file so you can do something like this.
List<String> readLines = Files.readAllLines(path, StandardCharsets.UTF_8);
readLines.set(acctNum- 1, data);
Files.write(path, lines, StandardCharsets.UTF_8);
I assumed that you are using Java 7 or higher so I did acctNum-1 because in Java 7 or higher version line number starts with 1 in rest it starts with 0 so you can change to acctNum.
Reference: List set() and NIO
This is my assignment - Write a program that reads a file and removes all comma’s from it and writes it back out to a second file. It should print to the console window, at the end, the number of comma’s removed.
The program needs to:
Prompt the user for the name of the file to read.
Reads file
Write the non-comma characters to output.txt, including all spaces.
When done reading the input file, write the total number of comma’s removed to the console window.
For example, if the input file contains 3+,2 = 5m, 7%,6 =1 hello
Then the output.txt file should contain:
3+2=5m 7%6=1 hello
And the console window should print “Removed 3 commas”.
Right now I'm having trouble actually removing commas from my input file, I think I would write the line under my last if statment.
Tried figuring out how to remove commas from the input file
package pkg4.pkg4.assignment;
import java.util.Scanner;
import java.io.*;
/**
*
* #author bambo
*/
public class Assignment {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
Scanner keyboard = new Scanner(System.in);
System.out.println("What is the name of the inputfile?");
String inputfile = keyboard.nextLine();
File f = new File(inputfile);
Scanner inputFile = new Scanner(f);
System.out.println("Please enter the output file");
String outputfile = keyboard.nextLine();
FileWriter fw = new FileWriter(outputfile);
PrintWriter pw = new PrintWriter(fw);
int lineNumber=0;
while(inputFile.hasNext());
lineNumber++;
int commacount = 0;
String line = inputFile.nextLine();
if (line.length () != 0)
commacount++;
for(int i=0; i< line.length(); i++)
{
if(line.charAt(i) == ',');
{
commacount++;
}
pw.println("removed " + commacount + "commas");
}
}
}
According to your requirement for program i am suggesting you to use java 8 classes.for simplicity.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
public class Assignment {
public static void main(String[] args) throws IOException {
String content = "";
Scanner keyboard = new Scanner(System.in);
System.out.println("What is the name of the input file?");
String inputfile = keyboard.nextLine();
content = new String(Files.readAllBytes(Paths.get(inputfile)));
long total_numbers_of_char = content.chars().filter(num -> num == ',').count();
System.out.println("Please enter the output file");
content = content.replaceAll(",", "");
String outputfile = keyboard.nextLine();
Files.write(Paths.get(outputfile), content.getBytes());
System.out.println("removed " + total_numbers_of_char + " commas");
keyboard.close();
}
}
To print on console you should be using :
System.out.println("removed " + commacount + "commas");
To write the line in the output file without the commas :
pw.println(line.replaceAll(",",""));
guys iam new to java so please help me
iam making a simple app of exam app which that the teacher can input the Questions
and save it
when the student open the app they will be asked if they are students then the
app will start the Questions
i made 2 files Teacher file and Student file
here is the code
package com.belal.teacher;
import java.io.*;
import java.util.Scanner;
public class Teacher {
public static void main(String[] args) {
// 1 is the Q
// 2 choice 1
// 3 choice 2
// 4 choice 3
// 5 correct choice
// 6 grade of the Q
String userinput1;
String userinput2;
String userinput3;
String userinput4;
String userinput5;
String userinput6;
Scanner input1 = new Scanner(System.in);
Scanner input2 = new Scanner(System.in);
Scanner input3 = new Scanner(System.in);
Scanner input4 = new Scanner(System.in);
Scanner input5 = new Scanner(System.in);
Scanner input6 = new Scanner(System.in);
System.out.println(" enter the question: ");
userinput1 = input1.nextLine();
System.out.println(" enter answer 1 : ");
userinput2 = input2.nextLine();
System.out.println(" enter answer 2 : " );
userinput3 = input3.nextLine();
System.out.println(" enter answer 3 : " );
userinput4 = input4.nextLine();
System.out.println(" enter the correct answer : " );
userinput5 = input5.nextLine();
System.out.println("enter the grade of this Q : ");
userinput6 = input6.nextLine();
}
}
i want to call the input methods from this class under else i want to call the inputs from there under Else
package com.belal.student;
import java.util.Scanner;
import com.belal.teacher.Teacher;
public class Student {
public static void main(String[] args) {
System.out.println(" type (a) if u are a student type (b) if u are a teacher");
Scanner input = new Scanner(System.in);
input.nextLine();
if (input != input ) {
Teacher.main(args);
}else {
System.out.println();
}
}
}
It's a little hard to understand exactly what you're trying to do. At a minimum, it seems like you're trying to read/write to a database. If this is just for learning purposes and the read/write part isn't the main focus, you could just read/write to a text file. (Though if this is ever supposed to be multi-threaded that's a shoddy solution). Here's some code I wrote a while back for quick 'n' dirty reading/writing text.
import java.io.*;
import java.util.ArrayList;
public class TextIO {
/** Write a string to a text file at the given directory.
* #param f - directory, a string
* #param s - text to write
* #throws IOException
*/
public static void write(String f, String s) throws IOException {
write(new File(f), s);
}
/** Write a string to a text file at the given directory.
* #param f - directory, a file
* #param s - text to write
* #throws IOException
*/
public static void write(File f, String s) throws IOException {
FileWriter fr= new FileWriter(f);
BufferedWriter br= new BufferedWriter(fr);
br.write(s);
br.flush();
br.close();
}
/** Reads File f as a text file.
* #param f - the File to read
* #return - a String[], each entry of which is a line of text in f
* #throws IOException - if the file reading goes bad.
*/
public static String[] read(File f) throws IOException {
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(f);
br = new BufferedReader(fr);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
ArrayList<String> s = new ArrayList<String>();
while(br.ready()){
s.add(br.readLine());
}
br.close();
String[] sArray = new String[s.size()];
sArray = s.toArray(sArray);
return sArray;
}
}
If you want more specific help beyond this, try to break your question up into discrete tasks you're trying to accomplish.
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();
}
}