I'm trying to understand file I/O for class and I understand the basics but I'm having trouble understanding how to manage whats in the input file, the input file is formatted like this:
BusinessContact:firstName=Nikolaos;lastName=Tsantalis
SocialNetworkAccount:socialNetworkType=SKYPE;accountID=tsantalis
Basically my contact (which BusinessContact extends from) object has attributes of firstName, lastName and middleName,
it also has object attributes such as SocialNetworkAccount and such....
I don't need to be explained how my objects are formatted, those have been done all I'm trying to understand is how my file.txt in inputed into my program to set my Contact to a BusinessContact as well as setting the first and last name accordingly,
Thanks
EDIT: Im specifically told to use the split method which makes sense but I'm also told (1) create a common method for the parsing of attributes that returns a map where the keys correspond to the attributeNames and the values to the attributeValues (in this way you can reuse the same code)
You can use the Scanner class with different delimiters like below:
Scanner in = new Scanner(/**source*/);
in.useDelimiter(":");
String firstName, lastName;
String firstWord = in.next();
Scanner nameScanner = new Scanner(in.nextLine());
nameScanner.useDelimiter(";");
firstName = getName(new Scanner(nameScanner.next()));
lastName = getName(new Scanner(nameScanner.next()));
private String getName(Scanner nameScanner){
nameScanner.useDelimiter("=");
String nameTitle = nameScanner.next();
return nameScanner.next();
}
This way you read the text in parts as follows as follows:
BusinessContact:firstName=Nikolaos;lastName=Tsantalis
firstName=Nikolaos;lastName=Tsantalis
firstName=Nikolaos;lastName=Tsantalis
I hope this makes sense.
NOTE: This code reads only the first line. If you want to read the second i guess its not hard to modify it. If you want the second line too or if you have any issues let me know and i will update the answer.
EDIT: I just noticed that every line is formated the same way so basically you can use the same code for every line. Maybe in a loop like:
Scanner input = new Scanner(/**source*/);
while(input.hasNextLine()){
Scanner in = new Scanner(input.nextLine());
...
....
//The above code
}
String.split() method:
Scanner in = new Scanner(System.in);
String[] first = in.nextLine().split(":");
String[] second = first[1].split(";");
String[] thirdA = second[0].split("=");
String[] thirdB = second[1].split("=");
for(int i = 0; i < thirdA.length; i++){
System.out.println(thirdA[i]);
System.out.println(thirdB[i]);
}
For the first line, the above code will print:
firstName
lastName
Nikolaos
Tsantalis
Hope this helps.
You could use a regular expression, but you might feel more comfortable with String.split: Split on ":" and get the label, the split the second part on ";" to get the attributes, then split each attribute on "=" to get the key and the value.
Related
Sorry if a beginner question, but im trying to read contents from a file in java, and separate 3 strings with a / between them, ex: john/casey/lambert, how would I go along separating these three strings so I can store them into a firstName middleName and lastName variable. Im not sure how to get my scanner or code to recognize the / as a stopping point.
You can take the input in as string s = “John/Casey/lambert” and then you could split it into an array and take the values from there using s.split(“/“, -1)
String contents = "john/casey/lambert";
String contentsSplit[] = contents.split("/");
String firstName = contentsSplit[0]; //john
String lastName = contentsSplit[1]; //casey
One line from my text file (Students.txt) looks like this:
[Down Shirlee 1424 7185765304 HIS, BUS429, WRT008, PED105, ENG34, HIS534,A, KOR380,C, WRT837,C, CSE673,A, ENG475,C-, CIV561,B-, MAT318,C+, CIV796,A-, MUS586,A, HIS281,B, CHE314,A-, PHI353,B+ 2.53]
The format for each line in the Students.txt file is as follows:
first name, last name, unique id, phone number, major, coursesToTake, coursesTaking, coursesTaken, gpa
Now I need to take each argument (first name, last name, id, etc) and use it to create a Student object which is then added to an array of Students---> Student[] bag.
At first, my plan was this:
File file = new File("src/Students.txt");
Scanner in = new Scanner(file);
Student s = new Student();
i = 2000;
Student[] bag = new Student[i];
for(int p=0; p<i; p++){
String fName;
String str = in.nextLine();
for(int q=0; q<str.length(); q++){
String fName += str[q];
if(str[q] == " ");
s.setFirstName(fName);
}
//bag[p] = s;
}
The obvious problem with this method is after I get the first name, how do I continue the loop to get the rest of the arguments?
Since eventually, after each iteration on the first for loop:
for(int p=0; p<i; p++)
The
Student s
object would have all the proper arguments from the text file to which I can then:
studentBag[p] = s;
But after I get the first name, I do not understand how to get the rest of the arguments. Any suggestions?
Split by comma:
String[] args = line.split(",");
String name = args[0];
String secondNAme = args[1];
.....
Student s = new Student(name, secondNAme, ....)
Although the existing answer is correct, do you really need to implement this yourself?
Using a library like OpenCSV - http://opencsv.sourceforge.net - you can declare your class, annotate your fields with the column headings in the data and let it do all the work for you.
Not only is the code likely to be more readable, but also more stable, too. For a start, how do you handle if a quoted comma appears in your input data?
Trying to sort the doubles in descending order from my .txt file and print out the results, but why am I getting 4 lines of []?
My text file looks like this:
Mary Me,100.0
Hugh More,50.8
Jay Zee,85.0
Adam Cop,94.5
with my code that looks like this:
public static void sortGrade() throws IOException
{
Scanner input = new Scanner(new File("Grades.txt"));
while(input.hasNextLine())
{
String line = input.nextLine();
ArrayList<Double> grades = new ArrayList<Double>();
Scanner scan = new Scanner(line);
scan.useDelimiter(",");
while(scan.hasNextDouble())
{
grades.add(scan.nextDouble());
}
scan.close();
Collections.sort (grades,Collections.reverseOrder());
System.out.println(grades);
}
input.close();
}
I'd like for the output to look like this:
Hugh More,50.8
Jay Zee,85.0
Adam Cop,94.5
Mary Me,100.0
A push in the right direction would be great, thanks.
The problem is you're not reading in your values correctly!
You're reading in your line here:
String line = input.nextLine();
And then trying to parse it with a second one but this:
scan.hasNextDouble()
Will always return false as the first token in each string is the name! And it's not a double. You need to change the way you're parsing your input.
Furthermore if you want to sort both the name and the score at the same time you have to create an object that would encapsulate both name and grade and implement Comparable or write a custom Comparator for that type. Otherwise you'd have to make a Map mapping grade to each name, sort the grades and then print it in order while getting names for each grade (there can be multiple names for the same grade). This is not recommended because it does look clumsy.
Writing a comparable class really isn't that hard you just need to implement one method :-)
#Edit: you don't need a second scanner, if your format is set and that easy just use a split on that line like this:
String[] gradeName = line.split(",");
grades.add(Double.parseDouble(gradeName[1]));
If you can have more than 1 grade per person than instead of just getting gradeName[1] iterate over gradeName starting from the element at index 1 (since 0 is the name).
#Edit2:
You are creating a new grades list in the loop every time, so it will read one entry, add it to the list, sort it and print it. You should pull out everything except for those lines outside the while loop:
String line = input.nextLine();
String[] gradeName = line.split(",");
grades.add(Double.parseDouble(gradeName[1]));
#Edit3:
If you want an ascending order don't use Collections.reverseOrder(), just the default one:
Collections.sort (grades);
Say I have a string,
String templatePhrase = "I have a string that needs changing";
I also have a method to replace words in any given String. Here is the method:
public String replace(String templatePhrase, String token, String wordToPut) {
return templatePhrase.replace(token, wordToPut);
}
Now say (for the sake of my actual task) I have all the words in my String str in a List named wordsInHashtags. I want to loop through all the words in wordsInHashtags and replace them with words from another List named replacement using the replace() method. Each time the loop iterates, the modified String should be saved so it will hold its replacement(s) for the next loop.
I will post my code if anyone would like to see it, but I think it would confuse more than help, and all I am interested in is a way to save the modified String for use in the next iteration of the loop.
I was just reading about strings in beginning Java 2 the other day, :"Strings Objects are immutable" Cant be changes basically however StringBuffer Objects were created to deal with such a circumstance as i understand it. You could try:
StringBuffer templatePhrase = "I have a string to be changed";
templatePhrase.replace(token, wordToPut);
String replacedString = (String)templatePhrase;
Line 3 may cause a problem?
public class Rephrase {
public static void main(String[] args) {
/***
Here is some code that might help to change word in string. originally this is a Question from Absolute Java 5th edition. It will change two variable whatever you want but algorithm never change.So the input from keyboard or any other input source.
********/
String sentence = "I hate you";
String replaceWord = " hate";
String replacementWord = "love";
int hateIndex = sentence.indexOf(replaceWord);
String fixed = sentence.substring(0,hateIndex)+" "+replacementWord+sentence.substring(hateIndex+replaceWord.length());
System.out.println(fixed);
}
}
I've researched this subject thoroughly, including questions and answers on this website....
this is my basic code:
import java.util.Scanner;
class StringSplit {
public static void main(String[] args)
{
System.out.println("Enter String");
Scanner io = new Scanner(System.in);
String input = io.next();
String[] keywords = input.split(" ");
System.out.println("keywords" + keywords);
}
and my objective is to be able to input a string like "hello, world, how, are, you, today," and have the program break up this single string into an array of strings like "[hello, world, how, are, you, today]...
But whenever i compile this code, i get this output:
"keywords = [Ljava.lang.String;#43ef9157"
could anyone suggest a way for the array to be outputted in the way i require??
Sure:
System.out.println("keywords: " + Arrays.toString(keywords));
It's not the splitting that's causing you the problem (although it may not be doing what you want) - it's the fact that arrays don't override toString.
You could try using Java's String.Split:
Just give it a regular expression that will match one (or more) of the delimeters you want, and put your output into an array.
As for output, use a for loop or foreach look to go over the elements of your array and print them.
The reason you're getting the output you're getting now is that the ToString() method of the array doesn't print the array contents (as it would in, say, Python) but prints the type of the object and its address.
This code should work:
String inputString = new String("hello, world, how, are, you, today");
Scanner scn = new Scanner(inputString);
scn.useDelimiter(",");
ArrayList<String> words = new ArrayList<String>();
while (scn.hasNext()) {
words.add(scn.next());
}
//To convert ArrayList to array
String[] keywords = new String[words.size()];
for (int i=0; i<words.size(); ++i) {
keywords[i] = words.get(i);
}
The useDelimiter function uses the comma to separate the words. Hope this helps!