This question already has answers here:
Java - delete line from text file by overwriting while reading it
(3 answers)
Closed 8 years ago.
I have this file
1007 book1 5 3
1004 book2 4 1
1003 book3 3 0
1002 book4 2 1
and I am trying to delete the book number 1004 from the file, but before that I let the user enter the number of the book that he wants to delete.
First check if the book exists in the file or not, if the book is exists I delete it if not show "the book does not exists".
Scanner kb = new Scanner(System.in);
FileInputStream book = new FileInputStream("input.txt");
Scanner infile = new Scanner(book);
FileOutputStream out = new FileOutputStream("output.txt");
PrintWriter pw = new PrintWriter(out);
boolean found = false;
System.out.print("Enter the bookID : ");
int bID = kb.nextInt();
while(infile.hasNext()){
int id = infile.nextInt();
String title = infile.next();
int quantity = infile.nextInt();
int bQuantity = infile.nextInt();
if(bID == id){
found = true;
}
if(found == true){
pw.printf("%8d\t%-30s\t%8d\t%8d", infile.nextInt(), infile.next(), infile.nextInt(), infile.nextInt());
infile.nextLine();
System.out.println("The book has been deleted");
break;
}
}
if(found == false)
System.out.print("Not found");
pw.close();
infile.close();
I am trying to print all the file with out the book I have deleted.
You will need a book class, like this:
public class Book {
private int series;
private String name;
private int intA;
private int intB;
public Book(int series,String name, int intA, int intB) {
this.series = series;
this.name = name;
this.intA = intA;
this.intB = intB;
}
....
.... (add other methods as needed, you will definitely need a
toString() method, and getIntA(), getIntB(), getSeriesNum(),
getName() etc.)
}
When you use scanner to read the file, read them into an arraylist of type Book. When user enter a number, use a for loop to find the Book that matches that number, and remove that book object from your arraylist.
Also, try to keep data in memory and not write files too often. Writing files to disks is very inefficient comparing with changing data in memory. Once user is done with all his/her operations, you can use a printwriter to write the data to your file.
To read your file into this array of objects, you can do this:
public static ArrayList<Book> readbooklist() {
ArrayList<Book> booklist = new ArrayList<Book>();
File file = new File("path/filename.fileextension");
try {
Scanner scnr = new Scanner(file);
while (scnr.hasNextLine()) {
String entry = scnr.nextLine();
String [] parts = entry.split("\t"); // Depends on how data was delimited
int series = Integer.parseInt(parts[0]);
int intA = Integer.parseInt(parts[2]);
int intB = Integer.parseInt(parts[3]);
Book single = new Book(series, parts[1], intA, intB);
booklist.add(single);
}
scnr.close();
} catch (FileNotFoundException e) {
System.out.println("File Not Found!");
}
return booklist;
}
Remember to import proper dependency at the beginning of your class. Wish it helps!
I'd recommend to use a Map to store each line as value and the Id as the key only once. That way you don't have to reopen the file and read it each time you want to remove or add an entry, all you have to do is remove it and add it to the map. Once you are done, you can overwrite the old file you have by the values stored in the map or just create a new temp file to hold the data, delete the old file and then rename the temp file with old file's name
Store all the lines you would like to save in a String and close the scanner. Create a printwriter, print the string to the file and close it.
Example code:
File file = new File("yourTextFile.txt");
Scanner in = new Scanner(file);
String saveThisToFile = "";
while (in.hasNext()) {
String temp = in.nextLine();
if (condition to be true if you whant to keep this line) {
saveThisToFile += temp + "\n";
}
}
in.close();
PrintWriter printWriter = new PrintWriter(file);
printWriter.print(saveThisToFile);
printWriter.close();
Related
I have a program which reads some data under a file reader and then creates an instance of another class which models the data. Anyway that class works (has been tested with some hard coded values) but I now want to output the data of the instance of a Patient being read under the file reader but seem unable to.
Could anyone tell me where i'm going wrong.
You are not adding Patient instances to newPatient collection, that's why it's empty and you are not getting anything printed out. Add elements to queue:
while(scan.hasNextLine()){
String firstname = scan.nextLine();
String surname = scan.nextLine();
String illness = scan.nextLine();
int illnessSeverity = scan.nextInt();
String newLine = scan.nextLine();
newPatient.add(new Patient(firstname,surname,illness,illnessSeverity));
for (Patient newPatientData : newPatient) {
System.out.println(newPatientData);
}
You need to add data first to the Priority Queue. I think you missed that .
PriorityQueue<Patient> newPatient = new PriorityQueue<>();
File fileName = new File("patients.txt");
Scanner scan = null;
try {
scan = new Scanner(fileName);
while(scan.hasNextLine()){
String firstname = scan.nextLine();
String surname = scan.nextLine();
String illness = scan.nextLine();
int illnessSeverity = scan.nextInt();
String newLine = scan.nextLine();
Patient newP = new Patient(firstname,surname,illness,illnessSeverity);
newPatient.add(newP);
}
for (Patient newPatientData : newPatient) {
System.out.println(newPatientData);
}
} catch(Exception e) {
System.out.println("ERROR - file not found");
}
Most likely my biggest problem here is not fully understanding Hashmaps and how to manipulate them despite looking at some tutorials. Hopefully you wise souls will be able to point me in the right track.
I'm trying to read a .txt file into a hashmap. The text file contains the popularity of names for 2006. Each line of the inputFile contains a boys name and a girls name as well as how many were named that. For example: 1 Jacob 24,797 Emily 21,365 would be the input from the file for line 1.
I want to put the boys name into one list, and the girls names into a second list maintaining their current positions so that the user can search for jacob and be told it was the number 1 boys name that year, and so on for other names. Previously I was just reading the file line by line and seeing what line the file contained the name i was searching for. This worked, but it was unable to tell if it was a boys name or a girls name, resulting in errors where if I said i was searching for how popular Jacob was for girls, it would still say number 1. I determined a hashmap would be the best way around this, but can't really get it working.
My Code
public void actionPerformed(ActionEvent e)
{
//Parse Input Fields
String name = inputArea.getText();
if (name.equals(""))
{
JOptionPane.showMessageDialog(null, "A name is required.", "Alert", JOptionPane.WARNING_MESSAGE );
return;
}
String genderSelected = genderList.getSelectedItem().toString();
String yearSelected = yearList.getSelectedItem().toString();
String yearFile = "Babynamesranking"+yearSelected+".txt"; //Opens a different name file depending on year selection
boolean foundName = false;
Map<String, String> map = new HashMap<String,String>(); //Creates Hashmap
try
{
File inputFile = new File(yearFile); //Sets input file to whichever file chosen in GUI
FileReader fileReader = new FileReader(inputFile); //Creates a fileReader to open the inputFile
BufferedReader br = new BufferedReader(fileReader); //Creates a buffered reader to read the fileReader
String line;
int lineNum = 1; //Incremental Variable to determine which line the name is found on
while ((line = br.readLine()) != null)
{
if (line.contains(name))
{
outputArea.setText(""+name+" was a popular name during "+yearSelected+".");
outputArea.append("\nIt is the "+lineNum+" most popular choice for "+genderSelected+" names that year.");
foundName = true;
}
String parts[] = line.split("\t");
map.put(parts[0],parts[1]);
lineNum++;
}
fileReader.close();
}
catch(IOException exception)
{
exception.printStackTrace();
}
String position = map.get(name);
System.out.println(position);
}
Sample inputFile:
1 Jacob 24,797 Emily 21,365
2 Michael 22,592 Emma 19,092
3 Joshua 22,269 Madison 18,599
4 Ethan 20,485 Isabella 18,200
5 Matthew 20,285 Ava 16,925
6 Daniel 20,017 Abigail 15,615
7 Andrew 19,686 Olivia 15,474
8 Christopher 19,635 Hannah 14,515
Well, the problem is that by using
if (line.contains(name))
You're checking if the name exists in the whole line, regarding if it's a boy's name or a girl's name. What you can do is to read them separately, then decide which value you want to check. You can do something like this:
while ((line = br.readLine()) != null)
{
Scanner sc = new Scanner(line);
int lineNumber = sc.nextInt();
String boyName = sc.next();
int boyNameFreq = sc.nextInt();
String girlName = sc.next();
int girlNameFreq = sc.nextInt();
if(genderSelected.equals("male") && name.equals(boyName)){
// .. a boy's name is found
}
else if(genderSelected.equals("female") && name.equals(girlName)){
// .. a girl's name is found
}
}
Scanner class is used to parse the line, and read it token-by-token, so you can know if the name is for a boy or girl. Then check on the name that you need only.
You'll want two hashmaps, one for boys' names and one for girls' names - at present you're using boys' names as keys and girls' names as values, which is not what you want. Instead, use two Map<String, IntTuple> data structures where the String is the name and the IntTuple is the line number (rank) and the count of people with this name.
class IntTuple {
final int rank;
final int count;
IntTuple(int rank, int count) {
this.rank = rank;
this.count = count;
}
}
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 6 years ago.
I have my program which reads from a txt file, then turns txt information into a car object and adds them to an arraylist.
try {
String filePath = "car.txt";
File f = new File(filePath);
Scanner sc = new Scanner(f);
List<Car> car = new ArrayList<Car>();
while(sc.hasNextLine()){
String newLine = sc.nextLine();
String[] details = newLine.split(" ");
String brand = details[0];
String model = details[1];
double cost = Double.parseDouble(details[2]);
Car c = new Car(brand, model, cost);
Car.add(c);
}
However, If a line from the txt file does not contain the three components then it crashes. How would I check if the line contains all 3 components, if not print a message then terminate?
Stack trace -
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at Main.loadPerson(Main.java:31)
at Main.main(Main.java:12)
You need to check for the length of details is 3, if not exit as shown below:
String[] details = newLine.split(" ");
if(details.length != 3) {
System.out.println("Incorrect data entered !! Please try again !!! ");
return;
} else {
String brand = details[0];
String model = details[1];
double cost = Double.parseDouble(details[2]);
Car c = new Car(brand, model, cost);
Car.add(c);
}
You can check the length of return array from split by:
int count = details.length;
and then decide what to do
check length before accessing elements,
try the pattern \\s+ to avoid trimming spaces, there is a typo in your code where adding Car to car list
while (sc.hasNextLine()) {
String newLine = sc.nextLine();
String[] details = newLine.split("\\s+");
if (details.length == 3) {
String brand = details[0];
String model = details[1];
double cost = Double.parseDouble(details[2]);
Car c = new Car(brand, model, cost);
car.add(c);
} else {
System.out.println("Invalid input");
}
}
If the file doesn't contain the 3 components, then details will be empty. use this instead.
if(details.length() != 3){
System.out.println("Invalid .txt file!");
break;
}
I am writing a method that will take in some command line arguments, validate them and if valid will edit an airport's code. The airport name and it's code are stored in a CSV file. An example is "Belfast,BHD". The command line arguments are entered as follows, java editAirport EA BEL Belfast, "EA" is the 2letter code that makes the project know that I want to Edit the code for an Airport, "BEL" is the new code, and Belfast is the name of the Airport.
When I have checked through the cla's and validated them I read through the file and store them in an ArrayList as, "Belfast,BEL". Then I want to update the text file by removing the lines from the text file and dumping in the arraylist, but I cannot figure out how to do it. Can someone show me a way using simple code (no advanced java stuff) how this is possible.
Here is my program
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.text.*;
public class editAirport
{
public static void main(String [] args)throws IOException
{
String pattern = "[A-Z]{3}";
String line, line1, line2;
String[] parts;
String[] parts1;
boolean found1 = false, found2 = false;
File file = new File("Airports.txt"); // I created the file using the examples in the outline
Scanner in = new Scanner(file);
Scanner in1 = new Scanner(file);
Scanner in2 = new Scanner(file);
String x = args[0], y = args[1], z = args[2];
//-------------- Validation -------------------------------
if(args.length != 3) // if user enters more or less than 3 CLA's didplay message
JOptionPane.showMessageDialog(null, "Usage: java editAirport EA AirportCode(3 letters) AirportName");
else if(!(file.exists())) // if "Airports.txt" doesn't exist end program
JOptionPane.showMessageDialog(null, "Airports.txt does not exist");
else // if everything is hunky dory
{
if(!(x.equals("EA"))) //if user doesn't enter EA an message will be displayed
JOptionPane.showMessageDialog(null, "Usage: java editAirport EA AirportCode(3 letters) AirportName");
else if(!(y.matches(pattern))) // If the code doesn't match the pattern a message will be dislayed
JOptionPane.showMessageDialog(null, "Airport Code is invalid");
while(in.hasNext())
{
line = in.nextLine();
parts = line.split(",");
if(y.equalsIgnoreCase(parts[1]))
found1 = true; //checking if Airport code already is in use
if(z.equalsIgnoreCase(parts[0]))
found2 = true; // checking if Airport name is in the file
}
if(found1)
JOptionPane.showMessageDialog(null, "Airport Code already exists, Enter a different one.");
else if(found2 = false)
JOptionPane.showMessageDialog(null, "Airport Name not found, Enter it again.");
else
/*
Creating the ArrayList to store the name,code.
1st while adds the names and coses to arraylist,
checks if the name of the airport that is being edited is in the line,
then it adds the new code onto the name.
sorting the arraylist.
2nd for/while is printing the arraylist into the file
*/
ArrayList<String> airport = new ArrayList<String>();
while(in1.hasNext()) // 1st while
{
line1 = in1.nextLine();
if(line1.contains(z))
{
parts1 = line1.split(",");
parts1[1] = y;
airport.add(parts1[0] + "," + parts1[1]);
}
else
airport.add(line1);
}
Collections.sort(airport); // sorts arraylist
FileWriter aFileWriter = new FileWriter(file, true);
PrintWriter output = new PrintWriter(aFileWriter);
for(int i = 0; i < airport.size();)
{
while(in2.hasNext()) // 2nd while
{
line2 = in2.nextLine();
line2 = airport.get(i);
output.println(line2);
i++;
}
}
output.close();
aFileWriter.close();
}
}
}
}
The Airports.txt file is this
Aberdeen,ABZ
Belfast City,BHD
Dublin,DUB
New York,JFK
Shannon,SNN
Venice,VCE
I think your problem may lie in the two lines:
line2 = in2.nextLine();
line2 = airport.get(i);
this will overwrite the 'line2' in memory, but not in the file.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
So i have a tiny problem, for some reason I'm blanking and I've tried moving it inside the loop and back to the outside of the loop it doesn't work. In option two which returns method display_names it reads them from the file it writes them to the console on one line instead of two separate lines.
ex:
Enter two knew people clicking 3:
smith, rob, 123-123-1234
smith, tom, 123-123-1235
Display names by clicking 2:
smith, rob, 123-123-1234smith, tom, 123-123-1235
instead of:
smith, rob, 123-123-1234
smith, tom, 123-123-1235
Main Code:
import java.util.*;
import java.io.*;
public class ContactList
{
/**
Contact list file name
*/
private String filename;
String findMe;
/**
ContactList constructor accepts a String parameter
*/
public ContactList(String inFileName)
{
filename = inFileName;
}
/**
3) add a new record to the file. Open the file for writing in append mode(there is a FileWriter constructor with the appropriate parameters).
a) prompt the user to enter data for each field in the record. Each field is a String.
The last name is required. If the last name is the empty string(""), return to the menu.
b) when the user has completed entering data(i.e., all the fields have been prompted), re-display the user choices
c) do not overwrite existing data
*/
public void new_record()
{
/*
Prompt for data:
Last name
First name
Phone
*/
//Create a scanner object
Scanner scan = new Scanner(System.in);
//prompt for the last name
System.out.println("Last Name: ");
//input the last name
String lastName = scan.next();
//the Last_name must not be empty
if(lastName.length() > 0)
{
//get the first name and the phone
System.out.println("Enter First Name: ");
String firstName = scan.next();
System.out.println("Enter phone number(xxx-xxx-xxxx): ");
String phone = scan.next();
//create the output string
String info = String.format("%s, %s, %s", lastName, firstName, phone);
//Declare variables to hold file types
File file = new File(filename);
//try to open the file for writing - append the data
try
{
if(!file.exists()){
PrintWriter out = new PrintWriter(filename);
out.println(info);
out.flush();
out.close();
}
else if(file.exists()){
FileWriter fw = new FileWriter(filename, true);
fw.write(info);
fw.close();
}
}
catch(IOException ioe)
{
System.out.println("new_record: Exception opening the file for writing");
}
}//end of test of Last_name
}//end of new_record
/**
2) display all last names and first names in the file.
Open the file for reading, read each record and
display the field values.
a) display all the lastName, firstName paired fields in the file;
display with the format lastName, firstName
b) when all records have been displayed, display the record count - the record count is the number of records read and should equal the number of records in the file
c) after all the records and the count have been displayed, display the user choices
*/
public void display_names()
{
//delare variables to hold file types
File file = new File(filename);
//try to open the file for reading
try
{
if(file.exists()){ //if the file exists allow it to be read
BufferedReader br = new BufferedReader(new FileReader(filename)); //Allows the file to be read line by line
String line = br.readLine();
int count = 0;
System.out.println("");
while(line != null){
System.out.println(line);
line = br.readLine();
count++;
}
System.out.println("");
System.out.println("Total records read: " +count);
br.close();
}
}
catch(IOException ioe)
{
System.out.println("display_names: Exception opening the file");
}
}//end of display_names
/**
1) search an address file for a particular last name
and then display the Last name, the first name, and
the phone for each match
2) display the count of records which match the last name
*/
public void search(String LastName)
{
//Declare variables to hold file types
File file = new File(filename);
this.findMe = LastName;
//try to open the file for reading
try
{
if(file.exists()){
BufferedReader br = new BufferedReader(new FileReader(filename)); //Allows the file to be read line by line
String s="", line = null;
int count = 0;
while((line = br.readLine()) != null){
String [] parts = line.split(",");
if(parts[0].equals(findMe)){
count = 1;
s= line;
}
}
System.out.println("\n"+s+"\n");
System.out.println("Total matching records found: " +count);
br.close();
}
}
catch(IOException ioe)
{
System.out.println("search: Exception opening the file");
}
}//end of search
}//end of class
Tester Code:
import java.util.*;
public class TestContactList
{
/**
main
*/
public static void main(String args [])
{
final int ONE = 1;
final int TWO = 2;
final int THREE = 3;
final int FOUR = 4;
final int FIVE = 5;
Scanner scan = new Scanner(System.in);
/*
*/
while(true)
{
System.out.println("1) Search an address file for a particular last name ");
System.out.println("2) Display all last names and first names in the file ");
System.out.println("3) Add a new record to the file ");
System.out.println("4) End the program ");
System.out.print("Please choose 1 - 4: ");
int choice = scan.nextInt();
scan.nextLine();
/*
Create a new ContactList object with the name of the
contact list file.
*/
ContactList cl = new ContactList("MyAddressBook.txt");
/*
if 4 exit program
*/
if(choice == FOUR)
{
System.exit(0);
}
/*
if 1 call search method
*/
if(choice == ONE)
{
System.out.print("Enter name to find: ");
String findMe = scan.nextLine();
cl.search(findMe);
}
/*
if 2 call display_names method
*/
if(choice == TWO)
{
cl.display_names();
}
/*
if 3 call new_record method
*/
if(choice == THREE)
{
cl.new_record();
}
}//end of while loop
}//end of main
}
thanks in advance xD, I think this should be a simple fix
well, it seems that the data files are the ones missing here :-) but from your code
while((line = br.readLine()) != null){
s += line;
count++;
}
System.out.println("\n"+s+"\n");
it seems that you're appending your items into "s" and only in the end you're embracing it between newlines.
Instead, I think you should add the newline inside the while loop.
Of course, there are other issues like using StringBuilder or StringBuffer to concatenate strings.
Your format string (String.format) needs to have a line separator.