Java read from a textfile and get all values inbetween parentheses - java

I've got the following code which reads my text file and gets the value inside the parentheses.
String content = new Scanner(new File(hello.txt)).useDelimiter("\\Z").next();
double value = Double.parseDouble(content.substring(content.indexOf("(") + 1, content.indexOf(")")));
System.out.println(value);
How can I change it so if the text file has multiple parentheses, it prints them all?
A sample text file would look something like this:
334.43 (0.03037)
655.32 (1.203)
734234.5948 (232.4358)
78764.342 (564.342342)
So I want the output to be:
0.03037
1.203
232.4358
564.342342

Use a loop and read the file line by line
Scanner sc = new Scanner(new File(hello.txt)).useDelimiter("\\Z");
while (sc.hasNextLine()) {
String content = sc.nextLine();
double value = Double.parseDouble(content.substring(content.indexOf("(") + 1, content.indexOf(")")));
System.out.println(value);
}

Related

Read file using delimiter and add to array

I am trying to read from a text file that is in my project workspace then;
Create an object depending on the first element on the first line of the file
Set some variables within the object
Then add it to my arrayList
I seem to be reading the file ok but am struggling to create the different objects based off what the first element on each line in the text file is
Text file is like this
ul,1,gg,0,33.0
sl,2,hh,0,44.0
My expected result is to create an UltimateLanding object or StrongLanding object based on the first element in the text above file example
Disclaimer - I know the .equals is not correct to use in the IF statement, i've tried many ways to resolve this
My Code -
Edited -
It seems the program is now reading the file and correctly and adding to the array. However, it is only doing this for the first line in the file? There should be 2 objects created as there are 2 lines in the text file.
Scanner myFile = new Scanner(fr);
String line;
myFile.useDelimiter(",");
while (myFile.hasNext()) {
line = myFile.next();
if (line.equals("sl")) {
StrongLanding sl = new StrongLanding();
sl.setLandingId(Integer.parseInt(myFile.next()));
sl.setLandingDesc(myFile.next());
sl.setNumLandings(Integer.parseInt(myFile.next()));
sl.setCost(Double.parseDouble(myFile.next()));
landings.add(sl);
} else if (line.equals("ul")) {
UltimateLanding ul = new UltimateLanding();
ul.setLandingId(Integer.parseInt(myFile.next()));
ul.setLandingDesc(myFile.next());
ul.setNumLandings(Integer.parseInt(myFile.next()));
ul.setCost(Double.parseDouble(myFile.next()));
landings.add(ul);
}
}
TIA
There are multiple issues with your current code.
myFile.equals("sl") compares your Scanner object with a String. You would actually want to compare your read string line, not your Scanner object. So line.equals("sl").
nextLine() will read the whole line. So line will never be equal to "sl". You should split the line using your specified delimiter, then use the split parts to build your object. This way, you will not have to worry about newline in combination with next().
Currently, your evaluation of the read input is outside of the while loop, so you will read all the content of the file, but only evaluate the last line (currently). You should move the evaluation of the input and creation of your landing objects inside the while loop.
All suggestions implemented:
...
Scanner myFile = new Scanner(fr);
// no need to specify a delimiter, since you want to read line by line
String line;
String[] splitLine;
while (myFile.hasNextLine()) {
line = myFile.nextLine();
splitLine = line.split(","); // split the line by ","
if (splitLine[0].equals("sl")) {
StrongLanding sl = new StrongLanding();
sl.setLandingId(Integer.parseInt(splitLine[1]));
sl.setLandingDesc(splitLine[2]);
sl.setNumLandings(Integer.parseInt(splitLine[3]));
sl.setCost(Double.parseDouble(splitLine[4]));
landings.add(sl);
} else if (splitLine[0].equals("ul")) {
UltimateLanding ul = new UltimateLanding();
ul.setLandingId(Integer.parseInt(splitLine[1]));
ul.setLandingDesc(splitLine[2]);
ul.setNumLandings(Integer.parseInt(splitLine[3]));
ul.setCost(Double.parseDouble(splitLine[4]));
landings.add(ul);
}
}
...
However, if you don't want to read the contents line by line (due to whatever requirement you have), you can keep reading it via next(), but you have to specify the delimiter correctly:
...
Scanner myFile = new Scanner(fr);
String line; // variable naming could be improved, since it's not the line
myFile.useDelimiter(",|\\n"); // comma and newline as delimiters
while (myFile.hasNext()) {
line = myFile.next();
if (line.equals("sl")) {
StrongLanding sl = new StrongLanding();
sl.setLandingId(Integer.parseInt(myFile.next()));
sl.setLandingDesc(myFile.next());
sl.setNumLandings(Integer.parseInt(myFile.next()));
sl.setCost(Double.parseDouble(myFile.next()));
landings.add(sl);
} else if (line.equals("ul")) {
UltimateLanding ul = new UltimateLanding();
ul.setLandingId(Integer.parseInt(myFile.next()));
ul.setLandingDesc(myFile.next());
ul.setNumLandings(Integer.parseInt(myFile.next()));
ul.setCost(Double.parseDouble(myFile.next()));
landings.add(ul);
}
}
...
A solution.
List<Landing> landings = Files.lines(Paths.get("LandingsData.txt")).map(line -> {
String[] split = line.split(",");
if (split[0].equals("sl")) {
StrongLanding sl = new StrongLanding();
sl.setLandingId(Integer.parseInt(split[1]));
sl.setLandingDesc(split[2]);
sl.setNumLandings(split[3]);
sl.setCost(Double.parseDouble(split[4]));
return sl;
} else if (split[0].equals("ul")) {
UltimateLanding ul = new UltimateLanding();
ul.setLandingId(Integer.parseInt(split[1]));
ul.setLandingDesc(split[2]);
ul.setNumLandings(split[3]);
ul.setCost(Double.parseDouble(split[4]));
return ul;
}
return null;
}).filter(t -> t!= null).collect(Collectors.toList());

Why is the file reading the last line of a row and the first one of the second row

While reading a Excel CSV file using a scanner with a comma delimiter, its reading the last node in the first row but also reading the first node of the next row at the same time.
int counter = 0;
String[] u = new String[3];
for (int j = 1; j <= 3; j++) {
String a = in.next();
u[counter] = a;
counter++;
}
}
After using Debugger, I noticed when it reached to the last element it combined them making something like -14256\r\n-14323
-14256 = Last element of first row
-14323 = First element of next row
The scanner took only the comma as the delimiter. But you want it to accept also the end of a line as another delimiter.
I assume that you instantiate the Scanner like this, using Scanner::useDelimiter:
Scanner s = new Scanner( inputStream ).useDelimiter( "," );
If I get the Pattern definition right, it should be:
Scanner s = new Scanner( inputStream ).useDelimiter( ",|\\R" );
The \R stands for
Linebreak matcher: Any Unicode linebreak sequence, is equivalent to \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
Refer to the documentation for java.util.regex.Pattern for the details.
A CSV file contains lines of text where each line contains values separated by commas. Hence I suggest that you read the file line by line and then split each line on the commas. Something like...
java.io.FileReader fr = new java.io.FileReader("path to file");
java.io.BufferedReader br = new java.io.BufferedReader(fr);
String line = br.readLine();
while (line != null) {
String[] fields = line.split(",");
// Add code here to handle the "fields".
line = br.readLine();
}
Note that the above code is not a complete solution but a starting point. For instance, I haven't closed the BufferedReader.

change specific text in text file with scanner class (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.

looping method for a constructor

How should i loop this constructor? Arguments are passed from a text file. I've tried a while-loop, but it does not even read the first line of my text file. My text file contains the ff:
s0,a,s0,a,-1 (--next line--) s0,b,s0,b,-1. If I don't use a loop, it gets the contents of my text file, and passes it to the constructor.
EDIT: i've corrected and marked the constructor to be looped. If I include the second while-loop, it does not get the contents of the text file.
Edit2: the first while loop puts the contents of my text file to an array named argument. The 2nd while-loop does the looping for passing the contents of the argument array to the variables, which then passes it to the constructor. This 2nd while-loop doesn't work.
Scanner scanner = new Scanner(new File("D:\\Kirk\\Documents\\NetBeansProjects\\TuringMachine\\src\\turingmachine\\Algorithms.txt"));
String data = scanner.nextLine();
String[] arguments = data.split(",");
StringTokenizer st = new StringTokenizer(data);
int i = 0;
while (st.hasMoreTokens()) { //loop for putting contents of text file to array
arguments[i++] = st.nextToken();
}//end loop
while(scanner.hasNextLine()){ //loop transition function(not working)
String fromstate = arguments[0];
String read = arguments[1];
String tostate = arguments[2];
String write = arguments[3];
int move = Integer.parseInt(arguments[4]);
trans.add(new Transition(new StateTapeSymbolPair(fromstate, read), new StateTapeSymbolPair(tostate, write),move));
//loop the above constructor
}//end while
you are not looping to get data of eah line.
Here an example :
Scanner scanner = new Scanner(new File("Algorithms.txt"));
while(scanner.hasNext()){
String data = scanner.nextLine(); // your line
String[] arguments = data.split(","); // split the line
// getting data for each data inside the line
String fromstate = arguments[0];
String read = arguments[1];
String tostate = arguments[2];
String write = arguments[3];
int move = Integer.parseInt(arguments[4]);
System.out.println(fromstate+"-"+read+"-"+tostate+"-"+write+"-"+move);
}

Using useDelimiter to divide data from txt file

I have a data in a text file which is in format:
AB-9, Gregson, Brian, R T, Mr
I want to divide the up into and store the first one, AB-9, in a local variable, I have done all of that but the problem currently is that when I print the value of id, it prints with ,. How can I get rid of the extra comma?
Another issue is that the first line in the data is not being read.
public void readData()
{
File theNewData = new File("new_data.txt");
Scanner inputFrom = new Scanner(theNewData);
while(inputFrom.hasNextLine())
{
String lineOftext = inputFrom.nextLine().trim();
Scanner scanner = new Scanner(lineOftext).useDelimiter(",[ ]*");
String id = inputFrom.next();
System.out.println(id);
}
inputFrom.close();
}
Check out String.split()
Details at:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split%28java.lang.String%29

Categories

Resources