Using useDelimiter to divide data from txt file - java

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

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());

Inability to read data from a .txt file into an ArrayList because of a NoSuchElement exception

I have to create a program that quizzes the user on 10 multiple choice questions that must be read into the main class from a .txt file.
To do this so far, I've assigned the data in the .txt file to 10 Question objects with a while loop (under the hasNextLine condition). The Questions are then supposed to be stored in an ArrayList.
However, I am getting an exception that says "java.util.NoSuchElementException: No line found" at the point where the Scanner allegedly skips from the blank line to the next question. (fileInput.nextLine)
To clarify, the format of the text file is:
Question Text
Answer Option A
Answer Option B
Answer Option C
Answer Option D
Correct Answer
Incorrect Answer (1)
Incorrect Answer (2)
Incorrect Answer (3)
(Blank Line)
(repeat the above for the next question. The last question also ends with a blank line, at the end of the file).
I know that NoSuchElement exceptions happen when there is nothing left for the Scanner to read, but there is still data in the file that the Scanner should be reading even though it skips over the blank line.
I tried to move the for-loop (the one that puts the quizQuestion objects into the ArrayList) outside of the while loop, but then I get the error that the "quizQuestion" symbol can't be found. I also tried to make the while loop have the condition hasNextLine && index < questionList.size, which was effectively combining the two processes, but that caused it to skip to the very bottom of my program (the part that displays a goodbye message...not pictured) and not display any of the questions either. I have checked my .txt file and it's definitely formatted correctly so I don't know what the issue is at this point.
Here's my code:
// Create a new PrintWriter object and Scanner object that will read data from the file.
File quizFile = new File("fileWithTheQuestions.txt");
Scanner fileInput = new Scanner(quizFile);
// Create an ArrayList which will store the Question objects
ArrayList<myQuestion> questionList = new ArrayList<myQuestion>();
/* Assign the data about the questions in the .txt file to 10 Question objects in the correct order.
Also, read the Questions into the ArrayList. */
while(fileInput.hasNextLine())
{
// Assign the values in the .txt file to variables.
String question = fileInput.nextLine();
String choiceA = fileInput.nextLine();
String choiceB = fileInput.nextLine();
String choiceC = fileInput.nextLine();
String choiceD = fileInput.nextLine();
String correctAns = fileInput.nextLine();
String incorrectAns1 = fileInput.nextLine();
String incorrectAns2 = fileInput.nextLine();
String incorrectAns3 = fileInput.nextLine();
fileInput.nextLine(); //skips over blank space in the file. I think this is where the issue is!!!!!
// Use the variables as parameters for the Question objects' constructor.
myQuestion quizQuestion = new myQuestion(question, choiceA, choiceB, choiceC, choiceD, correctAns, incorrectAns1, incorrectAns2, incorrectAns3);
// Read the Questions into the ArrayList.
for (index = 0; index < questionList.size(); index++)
{
questionList.add(quizQuestion);
}
}
// Close the Scanner after all data has been read into the main class.
fileInput.close();
Ideally, the questions will print in a randomized order (using Collections.shuffle) which I have gotten to work successfully in a separate program when I was not using File I/O to import the data about the questions.
I'm pretty sure the problem is with the File I/O, but could it also be with the creation of the Question objects or the ArrayList?
Thanks anyone who can help with this.
EDIT: Here is the link to the .txt file.
Class for the Question object
public class myQuestion {
String question;
String choiceA;
String choiceB;
String choiceC;
String choiceD;
String correctAns;
String incorrectAns1;
String incorrectAns2;
String incorrectAns3;
public myQuestion(String question, String choiceA, String choiceB, String choiceC, String choiceD, String correctAns, String incorrectAns1, String incorrectAns2, String incorrectAns3) {
this.question = question;
this.choiceA = question;
this.choiceB = choiceB;
this.choiceC = choiceC;
this.choiceD = choiceD;
this.correctAns = correctAns;
this.incorrectAns1 = incorrectAns1;
this.incorrectAns2 = incorrectAns2;
this.incorrectAns3 =incorrectAns3;
}
#Override
public String toString() {
return this.question +
this.choiceA +
this.choiceB +
this.choiceC +
this.choiceD +
this.correctAns +
this.incorrectAns1 +
this.incorrectAns2 +
this.incorrectAns3 ;
}
}
Class for scanning the text data
public class FileScanning {
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
File quizFile = new File("resources/fileWithTheQuestions.txt");
Scanner fileInput = new Scanner(quizFile);
fileInput.useDelimiter("\\R+");
// Create an ArrayList which will store the Question objects
ArrayList<myQuestion> questionList = new ArrayList<myQuestion>();
/* Assign the data about the questions in the .txt file to 10 Question objects in the correct order.
Also, read the Questions into the ArrayList. */
while(fileInput.hasNext())
{
String question = fileInput.next();
String choiceA = fileInput.next();
String choiceB = fileInput.next();
String choiceC = fileInput.next();
String choiceD = fileInput.next();
String correctAns = fileInput.next();
String incorrectAns1 = fileInput.next();
String incorrectAns2 = fileInput.next();
String incorrectAns3 = fileInput.next();
// Use the variables as parameters for the Question objects' constructor.
myQuestion quizQuestion = new myQuestion(question, choiceA, choiceB, choiceC, choiceD, correctAns, incorrectAns1, incorrectAns2, incorrectAns3);
questionList.add(quizQuestion);
}
// Close the Scanner after all data has been read into the main class.
fileInput.close();
//printing the content scanned above
for(myQuestion quizQuestion : questionList) {
System.out.println(quizQuestion.toString());
}
}
}
I have used your sample input only.
The error occurs when reaching the last line of your file.
Your input file should either contain a trailing empty line or you should test for the existence of the blank line:
if (fileInput.hasNextLine()) {
fileInput.nextLine();
}

Split comma separated values in java, int and String

I have the following in a text file to import into an ArrayList:
Australia,2
Ghana,4
China,3
Spain,1
My ArrayList is made up of objects from another class, Team which has the fields TeamName and ranking. I can get the following to import the String and int into the team name, but I can't separate the number which is supposed to be the teams ranking:
public void fileReader()
{
try
{
String filename = "teams.txt";
FileReader inputFile = new FileReader(filename);
Scanner parser = new Scanner(inputFile);
for (Team teams : teams)
{
teams.setTeamName(parser.next());
teams.setRanking(parser.next()); //this doesn't work
}
}
catch (IOException e)
{
System.out.println("Cannot find file");
}
}
I'm guessing I have to use a split somewhere along the line, or convert a String to an integer??
Check out opencsv. It's 2018 and you shouldn't have to parse a text file yourself :).
By default scanner will use white space as delimiter
Override this by calling useDelimiter method in your case parser.useDelimiter(',');
Then for converting ranking string to int you parser.nextInt()
You can code something like below to suite your purpose.
You have two tokens in your use case i.e. comma (,) and new line (\n). As a result, next() can't be used in a straight forward way.
I am going over each line, then tokenizing each line on comma and finally getting subsequent tokens.
try
{
String filename = "teams.txt";
FileReader inputFile = new FileReader(filename);
Scanner parser = new Scanner(inputFile);
for (Team teams : teams)
{
String[] splitLine = sc.nextLine().split(","); // comma delimited array
teams.setTeamName(splitLine[0]);
teams.setRanking(splitLine[1]);
}
}
Scanner.next() read the next token from input stream, and give String.
If you want to read the next integer, you should use nextInt() instead:
teams.setRanking(parser.nextInt());
Edit
You got InputMismatchException because by default, Scanner use java whitespace as delimeter.
WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+")
In your case, the delimeter are comma , and new line \n so you should config the delimeter for your scanner:
Scanner parser = new Scanner(inputFile);
s.useDelimiter(",|\\n")
Another work around is to read the whole line and parse your line:
String line = parse.nextLine();
String[] parts = line.split(",");
team.setTeamName(parts[0]);
team.setRanking(Integer.parse(parts[1]));
You can choose one of the two solutions above

Java read from a textfile and get all values inbetween parentheses

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);
}

how to read the \n in a txt file for using in split

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

Categories

Resources