change specific text in text file with scanner class (java) - java

I write this code that can search for the some specific text (such as word) in the text file with scanner class, but i want also to replace (old text to the new text) in the same old text locuation.
i find in the internet that i must used replaceAll method like ( replaceAll(old, new); )
but it does't work with the scanner class.
This is my code, it just search (if it existed ) write new text in new line without change the old one.
Do i need to change the method (to get the data) form scanner to FileReader ??
File file = new File("C:\\Users....file.txt");
Scanner input = new Scanner(System.in);
System.out.println("Enter the content you want to change:");
String Uinput = input.nextLine();
System.out.println("You want to change it to:");
String Uinput2 = input.nextLine();
Scanner scanner = new Scanner(file).useDelimiter(",");
BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));
while (scanner.hasNextLine()) {
String lineFromFile = scanner.next();
if (lineFromFile.contains(Uinput)) {
lineFromFile = Uinput2;
writer.write(lineFromFile);
writer.close();
System.out.println("changed " + Uinput + " tO " + Uinput2);
break;
}
else if (!lineFromFile.contains(Uinput)){
System.out.println("Don't found " + Uinput);
break;
}
}

You cannot read from a file, then write to that same file. You need 2 different files.
while (read line from input file) {
if (NOT matches your search pattern)
write line to output file.
else { // matches
write start of line to your search pattern.
write your replace string
write from end of search pattern to end of line.
}
}
Unless your replace string is the same size as your search string, yes, you'll have to use 2 files. Consider the file:
Blah
Blah
Blah
Now replace the letter 'a' with "The quick Brown Fox". If you replace the first line, you've overwritten the rest of the file. Now you can't read the 2nd line, so YES, you'll have to use 2 files.

Here's another answer based on #Sedrick comment and your code.
I'm adding it to your pseudo code.
File file = new File("C:\\Users....file.txt");
Scanner input = new Scanner(System.in);
System.out.println("Enter the content you want to change:");
String Uinput = input.nextLine();
System.out.println("You want to change it to:");
String Uinput2 = input.nextLine();
Scanner scanner = new Scanner(file).useDelimiter(",");
java.util.List<String> tempStorage = new ArrayList<>();
while (scanner.hasNextLine()) {
String lineFromFile = scanner.next();
tempStorage.add(lineFromFile);
}
// close input file here
// Open your write file here (same file = overwrite).
// now loop through temp storage searching for input string.
for (String currentLine : tempStorage ) {
if (!lcurrentLine.contains(Uinput)){
String temp = currentLine.replace(Uinput, Uinput2);
write a line using temp variable
} else { // not replaced
write a line using currentLine;
}
// close write file here
By the way, you'll have to encase the reads writes with try catch to trap for IOExceptions. That's how I knew it was pseudo code. There are plenty of examples for reading/writing a file on this web site. It's easy to search for.

Related

Java delete lines in a file? [duplicate]

This question already has answers here:
Find a line in a file and remove it
(17 answers)
Removing Nth line of File with BufferedReader/BufferedWriter
(1 answer)
Closed 2 years ago.
I have a text file that will have repeated lines of the following information (without bullet points):
Code: 12345
john.doe#gmail.com
10935710517038750
In each "set", the numbers would be different as well as the email address. This is just an example.
What I want to do is scan through the text file, fine the line with the specific code I am searching for, then delete that code, email, and number line. Like, the line with the code in it as well as the next two lines.
I cannot, for the life of me, figure out how to do this. I learned how to replace these lines with something else, but I would like to erase them completely, preferably without having to make a brand new text file every single time, unless there is a way to make the new text file with the deleted lines, and replace the old file with this new one.
Here is the relevant code I have, in segments. The code replaces all lines matching the oldLine variable with an empty line. That isn't what I want, but I can't figure it out otherwise. I had gotten most of this code from an example elsewhere.
//Instantiating the File class
String filePath = "C:\\\\Users\\\\taylo\\\\Astronomy\\\\Which Bright Stars Are Visible\\\\StoreVerificationCodes.txt";
//Instantiating the Scanner class to read the file
Scanner sc = new Scanner(new File(filePath));
//instantiating the StringBuffer class
StringBuffer buffer = new StringBuffer();
//Reading lines of the file and appending them to StringBuffer
while (sc.hasNextLine()) {
buffer.append(sc.nextLine()+System.lineSeparator());
}
String fileContents = buffer.toString();
System.out.println("Contents of the file: "+fileContents);
//closing the Scanner object
sc.close();
String oldLine = "Code: 12345";
String newLine = "";
//Replacing the old line with new line
fileContents = fileContents.replaceAll(oldLine, newLine);
//instantiating the FileWriter class
FileWriter writer = new FileWriter(filePath);
System.out.println("");
System.out.println("new data: "+fileContents);
writer.append(fileContents);
writer.flush();
writer.close();
Well, I think, what you are looking for is substring method. I believe there would be some reason why you have this requirement where you just have the code and you have to delete the next two lines of that set also. Please have a look at below code. It should work, given that the structure of your file is fixed and not going to change.
String filePath = "C:/Users/taylo/Astronomy/Which Bright Stars Are Visible/StoreVerificationCodes.txt";
//Instantiating the Scanner class to read the file
Scanner sc = new Scanner(new File(filePath));
//instantiating the StringBuffer class
StringBuffer buffer = new StringBuffer();
//Reading lines of the file and appending them to StringBuffer
while (sc.hasNextLine()) {
buffer.append(sc.nextLine()+System.lineSeparator());
}
String fileContents = buffer.toString();
System.out.println("Contents of the file: "+fileContents);
//closing the Scanner object
sc.close();
String oldLine = "Code: 789678";
String newLine = "";
// My changes starts here.............
String codePattern = "Code:"; // A fixed pattern
int firstIndex = fileContents.indexOf(oldLine); // To get the index of code you looking for.
int nextIndex= fileContents.indexOf(codePattern, firstIndex+1);
if(nextIndex != -1) {
nextIndex = fileContents.indexOf(codePattern, firstIndex+1) -5;
fileContents = fileContents.substring(0, firstIndex) + fileContents.substring(nextIndex+3);
}
else
fileContents = fileContents.substring(0, firstIndex);
// My changes done here.............
//fileContents = fileContents.replaceAll(oldLine, newLine); //No need
FileWriter writer = new FileWriter(filePath);
System.out.println("");
System.out.println("new data: "+fileContents);
writer.append(fileContents);
writer.flush();
writer.close();

How can I remove specific elements from a linkedlist in java based on user input?

I'm very new (6 weeks into java) trying to remove elements from a csv file that lists a set of students as such (id, name, grades) each on a new line.
Each student id is numbered in ascending value. I want to try and remove a student by entering the id number and I'm not sure how I can do this.
So far I've just tried to reduce the value that user inputs to match the index as students are listed by number and I did this in a while loop. However, each iteration doesn't recognize the reduction from the previous user Input, and I think I need a way that can just search the value of the id, and remove the entire line from the csv file.
Have only tried to include the pertinent code. Reading previous stack questions has shown me a bunch of answers related to nodes, which make no sense to me since I don't have whatever prerequisite knowledge is required to understand it, and I'm not sure the rest of my code is valid for those methods.
Any ideas that are relatively simple?
Student.txt (each on a new line)
1,Frank,West,98,95,87,78,77,80
2,Dianne,Greene,78,94,88,87,95,92
3,Doug,Lei,78,94,88,87,95,92
etc....
Code:
public static boolean readFile(String filename) {
File file = new File("C:\\Users\\me\\eclipse-workspace\\studentdata.txt");
try {
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()) {
String[] words=scanner.nextLine().split(",");
int id = Integer.parseInt(words[0]);
String firstName = words[1];
String lastName = words[2];
int mathMark1 = Integer.parseInt(words[3]);
int mathMark2 = Integer.parseInt(words[4]);
int mathMark3 = Integer.parseInt(words[5]);
int englishMark1 = Integer.parseInt(words[6]);
int englishMark2 = Integer.parseInt(words[7]);
int englishMark3 = Integer.parseInt(words[8]);
addStudent(id,firstName,lastName,mathMark1,mathMark2,mathMark3,englishMark1,englishMark2,englishMark3);
}scanner.close();
}catch (FileNotFoundException e) {
System.out.println("Failed to readfile.");
private static void removeStudent() {
String answer = "Yes";
while(answer.equals("Yes") || answer.equals("yes")) {
System.out.println("Do you wish to delete a student?");
answer = scanner.next();
if (answer.equals("Yes") || answer.equals("yes")) {
System.out.println("Please enter the ID of the student to be removed.");
//tried various things here: taking userInput and passing through linkedlist.remove() but has never worked.
This solution may not be optimal or pretty, but it works. It reads in an input file line by line, writing each line out to a temporary output file. Whenever it encounters a line that matches what you are looking for, it skips writing that one out. It then renames the output file. I have omitted error handling, closing of readers/writers, etc. from the example. I also assume there is no leading or trailing whitespace in the line you are looking for. Change the code around trim() as needed so you can find a match.
File inputFile = new File("myFile.txt");
File tempFile = new File("myTempFile.txt");
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String lineToRemove = "bbb";
String currentLine;
while((currentLine = reader.readLine()) != null) {
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)) continue;
writer.write(currentLine + System.getProperty("line.separator"));
}
writer.close();
reader.close();
boolean successful = tempFile.renameTo(inputFile);

Replacing String placeholders with different characters

I'm in an intro cse class using Java and I have a new homework where I create a Mad Lib game using File Processing.
I am wondering what the best approach is to replace a String placeholder with an adjective like "cool"
Here is a small portion of my code
PrintStream fileOutput = new PrintStream(new File(fileName));
Scanner fileScan = new Scanner(new File(fileName));
while (fileScan.hasNextLine()) {
String line = fileScan.nextLine();
Scanner word = new Scanner(line);
while (word.hasNext()) {
String token = word.next();
if (token.startsWith("<") && token.endsWith(">")) {
token = token.replace("<", "");
token = token.replace(">", "");
}
fileOutput.print(token + " ");
}
}
I currently got the '<' and '>' characters taken care of but I am unsure what the best approach is to replace the characters in between the two brackets. For example if I identify a token is a placeholder and is adjective I would prompt the user to "Type an adjective" and a noun "Type a noun" using the correct a/an structure. On past assignments I would get the right external correctness but my style is "bad" or "incorrect"
How about something like this:
Scanner input = new Scanner(System.in);
// ...
while (word.hasNext()) {
String token = word.next();
if (token.startsWith("<") && token.endsWith(">")) {
token = token.substring(1, token.length() - 1);
String article = token.matches("(?i)[aeiou].*") ? "an" : "a";
System.out.println("Type " + article + " " + token);
token = input.next();
}
fileOutput.print(token + " ");
}
I'm not entirely sure if this is the answer you're looking for, but I'll give it a shot. It seems that you might be interested in a few things:
PrintWriter is a Java class which allows you to write to a file instead of scanning it like you do with Scanner. If you are meant to generate a mad libs response based on a template with tags for adjective, verb, etc. then what you probably want to do is scan the file and write contents to a new output as you parse them. To get user input, you can use a separate Scanner object which takes values from System.in. For example, you'll want to use something like:
PrintWriter writer = new PrintWriter(file);
Scanner scanner = new Scanner(file);
Scanner input = new Scanner(System.in);
(your previous code here)
if (token.startsWith("<") && token.endsWith(">")
{
System.out.println("Type a " + token + ":";
writer.write(input.next());
}
else
{
writer.write(token);
}
This clearly isn't perfect but hopefully you get the idea. If no tags are detected while scanning each word, then write the word to the file. If there is a tag detected, let the user define what is written in its place. Carry on for the rest of the file.
Edit: I just went back and saw that you use PrintStream. That will do the same thing. The purpose of my answer is demonstration of concept mostly.

Why doesn't my program recognize the last names properly?

The scanner reads the wrong data, the text file format is:
111,Smith,Sam, 40,10.50
330,Jones,Jennifer,30,10.00
The program is:
public class P3 {
public static void main(String[] args) {
String file=args[0];
File fileName = new File(file);
try {
Scanner sc = new Scanner(fileName).useDelimiter(", ");
while (sc.hasNextLine()) {
if (sc.hasNextInt( ) ){ int id = sc.nextInt();}
String lastName = sc.next();
String firstName = sc.next();
if (sc.hasNextInt( ) ){ int hours = sc.nextInt(); }
if (sc.hasNextFloat()){ float payRate=sc.nextFloat(); }
System.out.println(firstName);
}
sc.close();
} catch(FileNotFoundException e) {
System.out.println("Can't open file "
+ fileName + " ");
}
}
}
The output is:
40,10.50
330,Jones,Jennifer,30,10.00
It is supposed to be:
Sam
Jennifer
How do I fix it?
The problem is that your data isn't just delimited by commas. It is also delimited by line-endings, and also by Unicode character U+FF0C (FULLWIDTH COMMA).
I took your code, replaced the line
Scanner sc = new Scanner(fileName).useDelimiter(", ");
with
Scanner sc = new Scanner(fileName, "UTF-8").useDelimiter(", |\r\n|\n|\uff0c");
and then ran it. It produced the output it was supposed to.
The text , |\r\n|\n|\uff0c is a regular expression that matches either:
a comma followed by a space,
a carriage-return (\r) followed by a newline (\n),
a newline on its own,
a Unicode full-width comma (\uff0c).
These are the characters we want to delimit the text by. I've specified both types of line-ending as I'm not sure which line-endings your file uses.
I've also set the scanner to use the UTF-8 encoding when reading from the file. I don't know whether that will make a difference for you, but on my system UTF-8 isn't the default encoding so I needed to specify it.
First, please swap fileName and file. Next, I suggest you use a try-with-resources. Your variables need to be at a common scope if you intend to use them. Finally, when using hasNextLine() I would then call nextLine and you can split on optional white space and comma. That could look something like
String fileName = // ...
File file = new File(fileName);
try (Scanner sc = new Scanner(file)) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
String[] arr = line.split("\\s*,\\s*");
int id = Integer.parseInt(arr[0]);
String lastName = arr[1];
String firstName = arr[2];
int hours = Integer.parseInt(arr[3]);
float payRate = Float.parseFloat(arr[4]);
System.out.println(firstName);
}
} catch (FileNotFoundException e) {
System.out.println("Can't open file " + fileName + " ");
e.printStackTrace();
}

Finding and replacing words in a text file with Scanner and Printwriter classes

I'm currently attempting to write a program that can scan a text document and replace a specified word / string / whatever with another phrase, specifically using the classes Scanner and Printwriter. Unfortunately, I'm having a little bit of trouble finding the correct methods to use and how exactly to implement them. Here's my code:
class Redaction {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(System.in);
System.out
.println("Please enter the filename of the sensitive information");
String f = input.next();
System.out.println("Please input what text you want 'lost'");
String o = input.next();
System.out
.println("Please input what you want the new, improved filename to be called");
String n = input.next();
File sensitiveDocument = new File(f);
if (!sensitiveDocument.exists()) {
System.out.println("File does not exist.");
System.exit(0);
}
Scanner in = new Scanner(sensitiveDocument);
in.useDelimiter("[^A-Za-z]+");
PrintWriter out = new PrintWriter(n);
while (in.hasNext()) {
if (in.hasNext(o)) {
// ...
}
}
in.close();
out.close();
}
}
I'm pretty lost at this point. Any help would be much appreciated.
Start by reading PrintWriter and Scanner documentation, to decide which methods to use.
Pseodo code:
Get line by line (or word by word, depends on what you want to remove).
look for the string you want to remove
if the string contains the content to remove, remove it.
print the string to the file.
The simplest although not so efficient algorithm would be to read the contents of the file into a string variable. After which you could use a String Tokenizer to find and replace the word you don't want with the word you want and rewriting the contents of the variable back into the file.

Categories

Resources