I am not an experienced Java programmer and i'm trying to write some text to a file and then read it with Scanner. I know there are lots of ways of doing this, but i want to write records to file with delimiters, then read the pieces.
The problem is so small. When I look the output some printing isn't seen(shown in below). I mean the bold line in the Output that is only written "Scanner". I would be appreciated if anyone can answer why "String: " isn't seen there. (Please answer just what i ask)
I couldn't understand if it is a simple printing problem or a line end problem with "\r\n".
Here is the code:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class Tmp {
public static void main(String args[]) throws IOException {
int i;
boolean b;
String str;
FileWriter fout = new FileWriter("test.txt");
fout.write("Testing|10|true|two|false\r\n");
fout.write("Scanner|12|one|true|");
fout.close();
FileReader fin = new FileReader("Test.txt");
Scanner src = new Scanner(fin).useDelimiter("[|\\*]");
while (src.hasNext()) {
if (src.hasNextInt()) {
i = src.nextInt();
System.out.println("int: " + i);
} else if (src.hasNextBoolean()) {
b = src.nextBoolean();
System.out.println("boolean: " + b);
} else {
str = src.next();
System.out.println("String: " + str);
}
}
fin.close();
}
}
Here is the output:
String: Testing
int: 10
boolean: true
String: two
String: false
Scanner
int: 12
String: one
boolean: true
You're not setting your delimiter right; [|\\*] is a character class consisting of 2 characters, |, *.
String s = "hello|world*foo*bar\r\nEUREKA!";
System.out.println(s);
// prints:
// hello|world*foo*bar
// EUREKA!
Scanner sc;
sc = new Scanner(s).useDelimiter("[|\\*]");
while (sc.hasNext()) {
System.out.print("[" + sc.next() + "]");
}
// prints:
// [hello][world][foo][bar
// EUREKA!]
System.out.println();
sc = new Scanner(s).useDelimiter("\r?\n|\r|\\|");
while (sc.hasNext()) {
System.out.print("[" + sc.next() + "]");
}
// prints:
// [hello][world*foo*bar][EUREKA!]
You seemed to have found that "[|\\n]" "works", but this actually leaves a trailing \r at the end of some tokens.
Coincidentally, you should look up PrintWriter; it has println methods that uses the system property line.separator. It's basically what System.out is-a.
PrintWriter fout = new PrintWriter(new File("test.txt"));
fout.println("Testing|10|true|two|false");
The problem is that you are writing out the String "String: " and then writing out control character \r, or carriage return, and then writing out the contents.
The following version should work a bit better for you:
FileWriter fout = new FileWriter("test.txt");
fout.write("Testing|10|true|two|false\n");
fout.write("Scanner|12|one|true|");
fout.close();
FileReader fin = new FileReader("test.txt");
Scanner src = new Scanner(fin).useDelimiter("[|\n]");
To really see what I am talking about with the \r, you should change your original program so the print code looks like this:
} else {
str = src.next().trim();
str = str.replace('\n', '_');
str = str.replace('\r', '_');
System.out.println("String: " + str);
}
You should see the output:
String: false__Scanner
Related
So I would like to ask if there is any way to modify the code I currently have in order to make it so it only replaces certain parts of the text file.
Let's say I have a text file called TestFile1 that contains
A = Apple
B = Banana
C = Carrot
D = Durian
And another called TestFile2 which contains
A = Art
C = Clams
What I would like to happen is that the code should be able to compare the two text files and if it finds that there are two variables that match, the output file which would be TestFile3 would look like this
A = Art
B = Banana
C = Clams
D = Durian
Also, I would like to make it dynamic so that I don't have to change the code every single time that the variables are changed so it can be used for other text files.
At the moment, I currently only have this code, but what it only does is that it just fully replaces TestFile2 with TestFile1 entirely, which is not what I intend to happen.
import java.nio.file.Paths;
import java.nio.file.Path;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.charset.Charset;
import java.io.*;
import java.util.Scanner;
public class FindAndReplaceTest {
static void replaceTextFile(String fileName, String target, String replacement, String toFileName) throws IOException
{
Path path = Paths.get(fileName);
Path toPath = Paths.get(toFileName);
Charset charset = Charset.forName("UTF-8");
BufferedWriter writer = Files.newBufferedWriter(toPath, charset);
Scanner scanner = new Scanner(path, charset.name());
String line;
while (scanner.hasNextLine()) {
line = scanner.nextLine();
line = line.replaceAll(target, replacement);
writer.write(line);
writer.newLine();
}
scanner.close();
writer.close();
}
public static void main(String[] args) throws IOException{
replaceTextFile("C:\\Users\\LS1-10\\Documents\\TestFile2.txt", "Write", "Read", "C:\\Users\\LS1-10\\Documents\\TestFile1.txt");
/*
System.out.println("Note: Make sure files to merge are in the same directory as this program!");
Scanner in = new Scanner(System.in);
String output, file1name, file2name;
System.out.print("Enter output file name: ");
output = in.nextLine();
PrintWriter pw = new PrintWriter(output + ".txt");
System.out.print("Enter name of first file: ");
file1name = in.nextLine();
BufferedReader br = new BufferedReader(new FileReader(file1name + ".txt"));
String line = br.readLine();
System.out.print("Enter name of second file: ");
file2name = in.nextLine();
br = new BufferedReader(new FileReader(file2name + ".txt"));
line = br.readLine();
pw.flush();
br.close();
pw.close();
System.out.println("Replaced variables in " + file1name + ".txt with variables in " + file2name + ".txt into " + output + ".txt"); */
}
}
I commented out the part of the psvm that would ask for user input on what the file names would be because I just took it from a previous program that I made so all I need is something that would compare the two files and make the output appear as intended. Any help would be appreciated. Thank you!
The most elegant way, given everything fits into memory would be to:
deserialize file2 to a map
upon reading file1, check if the variable has an associated value in the map, and replace if needed before outputing to file3.
I'm taking an input string as Java source code, editing it a little bit, and generate a .java file in Java.
Here is my code.
BufferedWriter writer = new BufferedWriter(new FileWriter("javacode.java"));
//msg = msg.substring(4); //ignore this
String newcontent = "import java.io.BufferedWriter;import java.io.ByteArrayOutputStream;import java.io.FileWriter;import java.io.PrintStream;";
char[] content = msg.toCharArray();
int j = msg.indexOf("String[] args") + 14;
boolean inMain = false;
for (int x=0;x<content.length;x++) {
if (x == j) {
inMain = true;
if (content[j] != '{') {
j += 1;
newcontent += String.valueOf(content[x]);
continue;
}
newcontent += String.valueOf(content[x]);
String prefix = "ByteArrayOutputStream consoleStorage = new ByteArrayOutputStream();PrintStream newConsole = System.out;System.setOut(new PrintStream(consoleStorage));";
newcontent += prefix;
}
else if (content[x] == '}' && inMain) {
String post = "String str = consoleStorage.toString();try {BufferedWriter writer = new BufferedWriter(new FileWriter(\"javaoutput.txt\"));writer.write(str);writer.close();} catch (Exception e) {}";
newcontent += post;
newcontent += String.valueOf(content[x]);
inMain = false;
}
else {
newcontent += String.valueOf(content[x]);
}
}
writer.write(newcontent);
writer.close();
It may look a little bit complicated, but generally speaking, I'm adding these three pieces of code into the main method of the source code input.
//At the beginning of the program, insert the following code
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.PrintStream;
...
...
...
//At the beginning of the main method, insert the following code
ByteArrayOutputStream consoleStorage = new ByteArrayOutputStream();
PrintStream newConsole = System.out;
System.setOut(new PrintStream(consoleStorage));
...
...
...
//At the end of the main method, insert the following code
String str = consoleStorage.toString();
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("javaoutput.txt"));
writer.write(str);
writer.close();
} catch (Exception e) {}
However, when I test it out, with a simple Hello World example, I got this .java file.
Here is my source code input ("msg" variable, it is a simple String)
public class myClass {
public static void main(String[] args) {
System.out.println("Hello");
}
}
Here is what I got.
(I re-formatted this file for a better look)
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.PrintStream;
public class myClass {
ByteArrayOutputStream consoleStorage = new ByteArrayOutputStream();
PrintStream newConsole = System.out;
System.setOut(new PrintStream(consoleStorage));
public static void main(String[] args) {
System.out.println("Hello");
String str = consoleStorage.toString();
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("javaoutput.txt"));
writer.write(str);
writer.close();
} catch (Exception e) {}
}
}
As you can see, Java fails to put "[" and "]" into the file and write "[]" instead, and thus (probably) "int j = msg.indexOf("String[] args") + 14;" fails to locate the main method.
I tried many methods to fix this, including replacing "[" by "\\[" etc, none of them works. To be honest, I'm not even sure whether "[]" generates the problem.
Update:
I tested all contents of "msg" and "content" variable/array in different phases, by inserting the following test prints into my program.
Note:
CQ.sendPrivateMsg(msgReceiver, message) is used to send the message to the receiver, this is working appropriately.
"msg" variable is passed from the chatting software, which I can only use its API to send/receive messages, while I don't have its source code...
This program is a part of an plugin of a chatting software.
...
...
...
BufferedWriter writer = new BufferedWriter(new FileWriter("javacode.java"));
msg = msg.substring(4);
//test print 1
CQ.sendPrivateMsg(fromQQ, CC.at(fromQQ) + "\n" + msg);
String newcontent = "import java.io.BufferedWriter;import java.io.ByteArrayOutputStream;import java.io.FileWriter;import java.io.PrintStream;";
char[] content = msg.toCharArray();
//test print 2
CQ.sendPrivateMsg(fromQQ, CC.at(fromQQ) + "\n" + content[55] + content[56] + content[57] + content[58]);
//test print 3
String tempstr = new String();
for (int i=0;i<content.length;i++) {
tempstr += String.valueOf(content[i]);
}
CQ.sendPrivateMsg(fromQQ, CC.at(fromQQ) + "\n" + tempstr);
int j = msg.indexOf("String[] args") + 14;
...
...
...
The actual result is shown below
//test print 1: msg
public class myClass {
public static void main(String[] args) {
System.out.println("Hello");
}
}
//test print 2: char array, accessed each digit one by one
[
//test print 3: char array, concatenate in a loop and print out as a whole
public class myClass {
public static void main(String[] args) {
System.out.println("Hello");
}
}
It seems like the problem is triggered by the case when I tried to access a single value within the char array, but it is fine when I use a for loop to print it all.
Update:
I solved it, by replacing [ and other strange code in char array by [ or ].
Advice given in comment is very helpful. Appreciate!
It seems like msg is received as an HTML-encoded string.
You may use Apache Commons StringEscapeUtils.unescapeHtml4() to decode this string.
I am trying to format a text file. I want to delete all the new line characters except the ones that are used to start a new alinea. By that I mean if the line in the text file is whitespace I want to keep it but all the other newlines need to be deleted.
here is what I have so far:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
public class Formatting {
public static void main(String[] args) throws FileNotFoundException {
Scanner in = new Scanner(System.in);
System.out.println("give file name: ");
String filename = in.next();
File inputfile = new File(filename);
Scanner reader = new Scanner(inputfile);
String newline = System.getProperty("line.separator");
PrintWriter out = new PrintWriter("NEW " + filename);
while(reader.hasNextLine()) {
String line = reader.nextLine();
if (line.length() > 2 && line.contains(newline)) {
String replaced = line.substring(0,line.length()) + ' ';
out.print(replaced);
}
else {
out.print(line + ' ');
}
}
in.close();
out.close();
}
}
however now my first if statement never gets executed. Every newline just gets deleted.
Can anybody help me here? It would be very much appreciated.
This may help you , read comments to get idea what is the use of each line .
// 3. compress multiple newlines to single newlines
line = line.replaceAll("[\\n]+", "\n");
// 1. compress all non-newline whitespaces to single space
line = line.replaceAll("[\\s&&[^\\n]]+", " ");
// 2. remove spaces from begining or end of lines
line = line.replaceAll("(?m)^\\s|\\s$", "");
I would like to convert a body of text which is in a form similar to this:
text here
text there
text everywhere
into a single string which would look like the following:
textheretexttheretexteverywhere
EDIT: The text on multiple lines is to be copied from one file and pasted into the input of the program, however it isn't necessarily a .txt file.
Here's what I have so far:
public static void converter(String inputString){
String refinedString = inputString.replaceAll("\\s+","").replaceAll("\\\\n+", "");
System.out.println();
System.out.println("Refined string: " + refinedString);
}
Here is my main function where I am calling my converter method:
public static void main(String [] args){
System.out.println("Enter string: ");
Scanner input = new Scanner(System.in);
String originalString = input.nextLine();
System.out.println("Original string: " + originalString);
converter(originalString);
}
Many thanks in advance!
(I'm new to programming so sorry if I'm missing something really obvious, I've tried everything I could find on Stack overflow)
Try this:
String line = "";
File f = new File("Path to your file");
FileReader reader = new FileReader(f)
BufferedReader br = new BufferedReader(reader);
String str = "";
while((line = br.readlLine())!=null)
{
str += line;
}
System.out.println(str);
for spaces:
str = StringUtils.replace(str," ","");
You pretty much got it! The only thing you are "missing" is that you added the extra .replaceAll when you didn't need to.
Also, it sounds like you may have different types of input, but here is a solution based on your code:
EDIT: Here is the solution below:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String [] args){
System.out.println("Enter string: ");
Scanner input = new Scanner(System.in);
List<String> lines = new ArrayList<> ();
String line = null;
while (!(line = input.nextLine()).isEmpty()) {
lines.add(line);
}
StringBuilder myOriginalString = new StringBuilder();
for (String s : lines) {
myOriginalString.append(s);
myOriginalString.append(" ");
myOriginalString.append("\n");
}
String originalString = myOriginalString.toString();
System.out.println("Original string: \n" + originalString);
converter(originalString);
}
public static void converter(String inputString){
String refinedString = inputString.replaceAll("\\s+","");
System.out.println();
System.out.println("Refined string: " + refinedString);
}
}
Output:
Enter string:
text here
text there
text everywhere
Original string:
text here
text there
text everywhere
Refined string: textheretexttheretexteverywhere
Process finished with exit code 0
I did my best to model it around the type of input you would be giving. Based on your question, I assume you would be copying and pasting text to the prompt when you run your program. If you are looking to read from a file, then Mahbubur Rahman's answer is correct (and I won't replicate it in this answer as he deserves the credit.)
This should work.
String list = "text here\n";
list += "text there\n";
list += "text everywhere\n";
System.out.println("Original :\n"+list);
list= list.replace("\n", "").replace(" ", "");
System.out.println("New :\n"+list);
I'm actually developping a parser and I'm stuck on a method.
I need to clean specifics words in some sentences, meaning replacing those by a whitespace or a nullcharacter.
For now, I came up with this code:
private void clean(String sentence)
{
try {
FileInputStream fis = new FileInputStream(
ConfigHandler.getDefault(DictionaryType.CLEANING).getDictionaryFile());
BufferedReader bis = new BufferedReader(new InputStreamReader(fis));
String read;
List<String> wordList = new ArrayList<String>();
while ((read = bis.readLine()) != null) {
wordList.add(read);
}
}
catch (IOException e) {
e.printStackTrace();
}
for (String s : wordList) {
if (StringUtils.containsIgnoreCase(sentence, s)) { // this comes from Apache Lang
sentence = sentence.replaceAll("(?i)" + s + "\\b", " ");
}
}
cleanedList.add(sentence);
}
But when I look at the output, I got all of the occurences of the word to be replaced in my sentence replaced by a whitespace.
Does anybody can help me out on replacing only the exact words to be replaced on my sentence?
Thanks in advance !
There are two problems in your code:
You are missing the \b before the string
You will run into issues if any of the words from the file has special characters
To fix this problem construct your regex as follows:
sentence = sentence.replaceAll("(?i)\\b\\Q" + s + "\\E\\b", " ");
or
sentence = sentence.replaceAll("(?i)\\b" + Pattern.quote(s) + "\\b", " ");