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.
Related
I'm trying to scan a line of text from a .txt file, split it up into seven numbers, change two of the numbers, and then write the new numbers back into the .txt file. The code below works fine the first time, but seems to have issues with reading from the text file a second time for the new starting String. I've done very similar things multiple times and had no issues, so I'm really not sure why I'm having problems this time around. The code I currently have is:
public void addWin(int numGuesses) throws IOException {
FileWriter writer = new FileWriter(*filepath*);
Scanner scan = new Scanner(new File(*filepath*));
String temp = "0;0;0;0;0;0;0;";
if (scan.hasNextLine()) {
temp = scan.nextLine();
}
String[] statsArr = temp.split(";");
scan.close();
statsArr[0] = Integer.toString(Integer.parseInt(statsArr[0]) + 1);
statsArr[numGuesses] = Integer.toString(Integer.parseInt(statsArr[numGuesses]) + 1);
for (int i = 0; i < statsArr.length; i++) {
writer.append(statsArr[i] + ";");
}
writer.close();
}
Some extra context if needed, this is essentially for a Wordle clone sort of thing for a Discord bot I have. numGuesses is the number of guesses it took to get the word correct. The String being written in and being read is 7 numbers divided up by a semicolon, the first number is the current win streak, the second number is number of times you've won in 1 guess, and so on. The testing I've done seems to place the error somewhere before the scanner closes. A first run through will correctly write the numbers, so if the word was guessed in 3 attempts the file will contain "1;0;0;1;0;0;0;", but the next time the method is called it essentially starts from scratch. Checking the temp variable just after the if statement on a second run through just shows "0;0;0;0;0;0;0;". Sorry for the long-windedness, just trying to provide all possibly helpful details. Thank you in advance!
-
Consider the JavaDoc which states "Whether or not a file is available or may be created depends upon the underlying platform.". So what is happening here, is that when you use new FileWriter(*filepath*) the file is being locked/created blank, so when you use new Scanner(new File(*filepath*)); and scan.hasNextLine() you get a null/empty value.
The easy solution is to simply move the FileWriter further down in your code, and only open it after the scanner has been closed. Also add an else to your if statement so you know if there is an issue with reading from the scanner:
//Move the below line to be later in the code
//FileWriter writer = new FileWriter(*filepath*);
Scanner scan = new Scanner(new File(*filepath*));
String temp = "0;0;0;0;0;0;0;";
if (scan.hasNextLine()) {
temp = scan.nextLine();
}
//Add some debugging
else{
System.out.println("ERROR no data could be read");
}
String[] statsArr = temp.split(";");
scan.close();
statsArr[0] = Integer.toString(Integer.parseInt(statsArr[0]) + 1);
statsArr[numGuesses] = Integer.toString(Integer.parseInt(statsArr[numGuesses]) + 1);
//Create the flie writer here instead
FileWriter writer = new FileWriter(*filepath*);
for (int i = 0; i < statsArr.length; i++) {
writer.append(statsArr[i] + ";");
}
writer.close();
Now assuming the file exists and can be edited, and where numGuesses = 3, then for the following contents:
1;2;3;4;5;6;7;
The output of running the code is as expected (+1 to the 0 and 3rd index)
2;2;3;5;5;6;7;
The reason you only saw 0;0;0;0;0;0;0; was because the code was failing to read from the scanner, and always using the temp value from this line String temp = "0;0;0;0;0;0;0;";. By adding the else check above we can see when it fails.
FileWriter writer = new FileWriter(*filepath*); clears the contents of the file you are trying to read from. You need to move this line after scan.close();
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.
I need to read lines of text from a file that i have prompted from the user. My java program is supposed to read the first line of this file and check to see if the last word of that line appears anywhere in the second line. without using repetition, arrays, or class construction I have come up with this so far:
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter filename: ");
File userFile = new File(keyboard.nextLine());
keyboard.close();
Scanner input = new Scanner(userFile);
String firstLine = input.nextLine();
String secondLine = input.nextLine();
After here I have tried a lot of String methods but nothing is giving me back a satisfying result. I know I will need to finish my program with an if and else statement about whether or not the second line contains the last word in the first line.
**Having trouble finding a way to compare substrings (words within a line of text) that I do not actually know the location of or what the chars are. This is due to the fact that all the input is user generated. Is there even a way to compare substrings while retaining the actual chars and not converting to ints??
**UPDATE I AM ECSTATIC this is how I have solved this frustrating problem:
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter filename: ");
File userFile = new File(keyboard.nextLine());
keyboard.close();
Scanner input = new Scanner(userFile);
String firstLine = input.nextLine();
String secondLine = input.nextLine();
int lastWordIndex;
lastWordIndex = ((firstLine.lastIndexOf(" ")) + 1);
String lastWord = firstLine.substring(lastWordIndex);
if (secondLine.contains(lastWord))
System.out.println("It is true the word " + lastWord
+ " appears in the text: " + secondLine);
else
System.out.println("The word: " + lastWord
+ " does not appear in the text: " + secondLine);
There are several methods to do this, but you need to get the last word in the firstLine string, then compare it with the secondLine string.
You can use the substring() method on your line, then use the lastIndexOf() method with the argument " " (i.e. whitespace). If you add one to this you will have the index of the first letter of the last word in your string.
This is how I would do it:
String lastWord = firstLine.replaceAll(".*\\s+", "");
boolean secondLineHasLastWord = secondLine.contains(lastWord);
or, to in-line it:
if (secondLine.contains(firstLine.replaceAll(".*\\s+", ""))) {
// yes
} else {
// no
}
Extracting the last word is done using a regex that matches everything up to and including the last whitespace character and replaces the match with nothing (effectively deleting it).
I have this code here
java.io.File file=new java.io.File("deneme2.txt");
try{
Scanner input=new Scanner(file);
while(input.hasNext()){
String inputFile= input.nextLine();
String[] sequences =inputFile.split(" ");
It reads the file but I have to edit each file since I can not read .txt when the input is like this
ATGAGATACG
AGTCTCTAG
but I can read when I make
ATGAGATACG AGTCTCTAG
I tried to make \n and something like that but I couldn't.
So can you guys help me.
AND I know for sure that it has a very simple solution :) a solution that I'm not aware of tho
edit:in first example the 2 sequences are divided with a shift enter but the second one is divided with a single space
It sounds like you want to make the code that reads the file independent of the file format. To some extent, that's not possible. Any program has to assume some kind of pattern to the input -- be it XML, delimited text etc. So that breaks it up into two approaches: Either make the file fit the code or make the code fit the file.
From your description, I'm guessing you want to be able to read a sequence of characters that is delimited by whitespace -- any whitespace (' ', '\n', '\t'), yes? If that's true, don't limit yourself to reading by line. Just read each token. This, of course, assumes each token is what you want.
I created a test file with the content
abcd efg h
ijklm op
qrs
That has newlines, spaces and tabs. Then I fed it to the following code:
public static void main(String[] args){
try{
Scanner scanner = new Scanner(new File("testFile.txt"));
List<String> list = new ArrayList<String>();
while(scanner.hasNext()){
String s = scanner.next();
list.add(s);
}
scanner.close();
System.out.println(list);
}catch(FileNotFoundException e){
e.printStackTrace();
}
}
Which gives the output
[abcd, efg, h, ijklm, op, qrs]
Is it possible you want to create an array of sequences? Like you want this file
ATGAGATACG <-- each of these being a sequence
AGTCTCTAG
to become an array like this
String[] sequences = {"ATGAGATACG", "AGTCTCTAG"};
If that's the case, you can just do something like this
List<String> sequences = new ArrayList<String>(); <-- create a list
java.io.File file=new java.io.File("deneme2.txt");
try{
Scanner input = new Scanner(file);
while(input.hasNextLine()){
sequences.add(input.nextLine().trim()); <-- add to the list each line
}
Edit
If its only two lines why not just do this, and forget the loop
String s1;
String s2;
try {
Scanner input = new Scanner(file);
s1 = input.nextLine().trim();
s2 = input.nextLine().trim();
} catch(.. ){
}
// do something with s1
// do something with s2
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.