How to read next 10 characters after String variable - java

I have list of text files I need to read a specific string from, which is always preceded by the string "SWEUserName=". I have been able to print the entire line from the log, but not just the string I need. I do want to print the line number, just not the whole line
So far this is what I've got:
public static String [] openFile() throws FileNotFoundException, IOException{
String searchTech = "SWEUserName=";
int s;
String foundTech = "";
File logs = new File("C:\\Users\\wfedric\\Desktop\\GD\\Java\\Learning\\app\\src\\main\\java\\com\\fedrictechnologies\\learning\\FSDS2.txt");
Scanner scnr = new Scanner(logs);
int lineNumber = 1;
while(scnr.hasNextLine()){
String line = scnr.nextLine();
lineNumber++;
if(line.contains(searchTech)){
s = 10;
foundTech = lineNumber +" :"+ searchTech + s;
System.out.println(foundTech);
System.out.println(line);
}else;
}
return null;
}
I know I am missing something, but I can't for the life of me figure how to count the next 10 characters. I realize at it stands in my code, I am simply printing the Line number followed by my searchTech variable, and the number 10.
I need s to hold on to the 10 characters following searchTech. Perhaps an array is the best way? Just not sure :(
With the above code, I have the following output, which I should expect:
141 :SWEUserName=10
[09/04/14 EDT:8:15:48 AM- INFO- MASC1050141409832948329] - [ HomePageURL ] - ThinClient Home Page URL - https://wls.rio.directv.com/wpservsm_enu/start.swe?SWECmd=ExecuteLogin&SWENeedContext=false&SWEUserName=masc105014&SWEPassword=%5BNDSEnc-D%5Dji%2Fic25k%2FTB%2Fy7mqG2kcb2ndd1S3hgWC8Rfa4e1DvtwKWMGQmTzngA%3D%3D&
143 :SWEUserName=10
[09/04/14 EDT:8:15:48 AM- INFO- ] - [ webServiceRequest ] - Web service Call - RetryCounter: 0, URL: https://wls.rio.directv.com/wpservsm_enu/start.swe?SWECmd=ExecuteLogin&SWENeedContext=false&SWEUserName=masc105014&SWEPassword=%5BNDSEnc-D%5Dji%2Fic25k%2FTB%2Fy7mqG2kcb2ndd1S3hgWC8Rfa4e1DvtwKWMGQmTzngA%3D%3D&, Type: GET
1st and 3rd lines are the General format I want, 2nd and 4th lines are where I get stuck returning the specific values after searchTech.
SOLUTION (During this process, I played with the indexOf method to include the date, and left it there)
public class techMatching {
static int s;
static int d;
static String sTech;
static String dTech;
public static String [] openReadFile() throws FileNotFoundException, IOException{
String searchTech = "SWEUserName=";
String foundTech;
File logs = new File("C:\\FSDS2.txt");
Scanner scnr = new Scanner(logs);
int lineNumber = 1;
while(scnr.hasNextLine()){
String line = scnr.nextLine();
lineNumber++;
if(line.contains(searchTech)){
s = line.indexOf(searchTech);
sTech = line.substring(s+12,s+22);
d = line.indexOf("[");
dTech = line.substring(1, 22);
foundTech = lineNumber +": "+ "(" + dTech + ")" + "|"+ sTech.toUpperCase();
System.out.println(foundTech);
}else;
}
return null;
}
Which returned the expected output:
141: (09/04/14 EDT:8:15:48 )|MASC105014
143: (09/04/14 EDT:8:15:48 )|MASC105014
And so on.
"" ""

I suggest you look at the methods available in the String class. Using indexOf(searchTech), you know where in the line the "SWEUserName=" is. Using substring, you can get a String consisting of part of the line.

Related

I'm having problems with the .split() method using "," as the delimeter. Java

So for my current school project we have to read input from a file containing info on the periodic table of elements. Essentially I have to seperate bits of each line which has info on an element and put them into seperate string values.
Here the bit of code I'm having problems with.
for(int i=0;inputStream.hasNextLine();i++)
{
String line = inputStream.nextLine();
String[] info = line.split(",");
name=info[0];
atomicNumber=info[1];
symbol=info[2];
boilingPoint=info[3];
meltingPoint=info[4];
density=info[5];
molecularWeight=info[6];
elementInfo[i]= new Element(name,atomicNumber,symbol,boilingPoint,meltingPoint,density,molecularWeight);
It stores everything in the proper place except for the information for the density and the molecular Weight which i get null values for. I couldn't find any info why it isn't working for those last two Strings.
Example output:
Element Name: actinium
Atomic Number: 89
Symbol: Ac
Boiling Point: 3470
Melting Point: 1324
Density: null
Molecular Weight: null
Here's the constructor for the element object:
public Element(String name,String atomicNumber,String symbol, String boilingPoint, String meltingPoint, String density, String molecularWeight)
{
this.name=name;
this.atomicNumber=atomicNumber;
this.symbol=symbol;
this.boilingPoint=boilingPoint;
this.meltingPoint=meltingPoint;
this.density=density;
this.molecularWeight=molecularWeight;
}
You can try this,
// mean into file that info not exist, in that case take its default i.e. empty
info[5] == null ? "empty" : info[5];
info[6] == null ? "empty" : info[6];
Definitely the file you are reading contains 7 elements, else the following code will result in an error
density=info[5]; molecularWeight=info[6];
Example:
public static void main(String args[]) {
String line = "1,2,3,4,5,,";
String[] info = line.split(",");
System.out.println(info.length);
System.out.println(Arrays.deepToString(info));
}
The Output of the above snippet is 5 and [1, 2, 3, 4, 5]
Here we cannot use info[5] or info[6] as it will result in an error.
So your data is correct and you are capturing all the values.
I believe the problem is in printing the output, but you have not mentioned that code in your query to investigate deep.
Hope it helped.
String.split() never ever returns null (see here), which means the problem is not with split() method but, elsewhere. The split() method seem to return at least 7 chunks of data and this is because you are not getting ArrayIndexOutOfBoundException when you do this molecularWeight=info[6].
Then the problem is elsewhere and you can find out by reviewing your code and there must be something you are missing, something really really simple.
Let's assume you have the following input (2 elements):
actinium,89,Da,3470,1926,missing-x,missing-y
actinium,13,Gk,5480,1124,missing-z,missing-w
I used majority of your code, and developed a sample use cases to read the above two elements from file and store them in a list and print them back. I used List<Element> instead of your Element[] solution as well as overrided toString() in Element class to pretty-print the elements with Java 8's stream, see below and compare with your solution:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ReadFromFileElements {
public static void main(String... args) throws FileNotFoundException {
// You can use list instead of Element[] array
List<Element> elementInfo = new ArrayList<Element>();
//file containing the input
File file = new File("C:\\test_java\\elements.txt");
//open input stream to the file
Scanner input = new Scanner(file);
//as long as there is nextLine() keep looping
while(input.hasNextLine()) {
String line = input.nextLine();
String[] chunk = line.split(",");
Element e = new Element(chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], chunk[5],
chunk[6]);
//add to the list of Element/s
elementInfo.add(e);
}
//close input stream
input.close();
//java 8 stream iterator through collection
elementInfo.stream().forEach((temp) -> {
//temp.toString() uses the overrided toString() of element class
System.out.println(temp.toString());
});
}
}
class Element {
String name;
String atomicNumber;
String symbol;
String boilingPoint;
String meltingPoint;
String density;
String molecularWeight;
public Element(String name, String atomicNumber, String symbol, String boilingPoint, String meltingPoint,
String density, String molecularWeight) {
this.name = name;
this.atomicNumber = atomicNumber;
this.symbol = symbol;
this.boilingPoint = boilingPoint;
this.meltingPoint = meltingPoint;
this.density = density;
this.molecularWeight = molecularWeight;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("\n Element name: " + this.name);
builder.append("\n Atomic no: " + this.atomicNumber);
builder.append("\n Symobl : " + this.symbol);
builder.append("\n Boiling point : " + this.boilingPoint);
builder.append("\n Melting point : " + this.meltingPoint);
builder.append("\n Density : " + this.density);
builder.append("\n Molecular weight: " + this.molecularWeight);
return builder.toString();
}
}
And running the above code against the above two lines in the file, I get the following input:
Element name: actinium
Atomic no: 89
Symobl : Da
Boiling point : 3470
Melting point : 1926
Density : missing-x
Molecular weight: missing-y
Element name: actinium
Atomic no: 13
Symobl : Gk
Boiling point : 5480
Melting point : 1124
Density : missing-z
Molecular weight: missing-w
Use this
public static void readFileData(String filename) throws FileNotFoundException{
ArrayList<Element> list = new arrayList<>();
String split = ","; //split with comma
Scanner in = new Scanner(new File(filename));
String wordIn;
Element elem = new Element();
while (in.hasNextLine()) {
wordIn = in.nextLine();
String splitter[] = wordIn.split(split);
String name = splitter[0];
int atomicNumber = Integer.parseInt(splitter[1]);
String symbol = splitter[2];
String boilingPoint = splitter[3];
String meltingPoint = splitter[4];
String density = splitter[5];
String molecularWeight = splitter[6]
elem.setName(name);
elem.setAtomicNumber(atomicNumber);
elem.setSymbol(symbol);
elem.setBoilingPoint(boilingPoint);
elem.setMeltingPoint(meltingPoint);
elem.setDensity(density);
elem.setMolecularWeight(molecularWeight);
list.add(elem);
}
for(Element el : list){
sout(el.toString()) // if you have a to string method
}
}
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
String file = sc.next();
readFileData(file);
}
Make sure you have those setters in your Element class. And a too String method would be handy but not necessary. If the variable is type int in your Element class the you can do Integer.parseInt() or Double.parseDouble which converts string to integer or float etc. sout is short for System.out.println(); type sout + tab and you get the full thing.

Number format issue, newbie project

I am trying to write a program that loads a movie data base file, and then splits up that information into the movie title, year, and all of the associated actors. I split up all of the info, but I am having issues converting the year, which is in a string, to an int. The format of the year string is (****) with the * being a year, such as 1999. When I try to use parse I get a number format exception. I have tried replacing the parentheses, but it just gave me more errors! Any ideas?
public class MovieDatabase {
ArrayList<Movie> allMovie = new ArrayList<Movie>();
//Loading the text file and breaking it apart into sections
public void loadDataFromFile( String aFileName) throws FileNotFoundException{
Scanner theScanner = new Scanner(aFileName);
theScanner = new Scanner(new FileInputStream("cast-mpaa.txt"));
while(theScanner.hasNextLine()){
String line = theScanner.nextLine();
String[] splitting = line.split("/" );
String movieTitleAndYear = splitting[0];
int movieYearIndex = movieTitleAndYear.indexOf("(");
String movieYear = movieTitleAndYear.substring(movieYearIndex);
System.out.println(movieYear);
//this is where I have issues
int theYear = Integer.parseInt(movieYear);
String movieTitle = movieTitleAndYear.substring(0, movieYearIndex);
ArrayList<Actor> allActors = new ArrayList<Actor>();
for ( int i = 1; i < splitting.length; i++){
String[] names = splitting[i].split(",");
String firstName = names[0];
Actor theActor = new Actor(firstName);
ArrayList<Actor> allActor = new ArrayList<Actor>();
allActor.add(theActor);
}
Movie theMovie = new Movie(movieTitle, theYear, allActors);
allMovie.add(theMovie);
}
theScanner.close();
}
output:
(1967)
Here is the errors I am getting:
Exception in thread "main" java.lang.NumberFormatException: For input string: "(1967)"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:481)
at java.lang.Integer.parseInt(Integer.java:527)
at MovieDatabase.loadDataFromFile(MovieDatabase.java:27)
You have brackets around the numbers. You could either correct your file or you could remove brackets using:
String str = "(1967)";
System.out.println(str.substring(1, str.length()-1));
Output:
1967
In your code, you used:
int movieYearIndex = movieTitleAndYear.indexOf("(");
String movieYear = movieTitleAndYear.substring(movieYearIndex);
So if my movieTitleAndYear string is "hi (1947)", indexOf will give me index of "(" as 3 and substring will start reading string from index 3 which includes "(". One way you could avoid opening bracket is to change your substring line to:
String movieYear = movieTitleAndYear.substring(movieYearIndex + 1);//but still you have closing bracket.
If you are sure it's always going to be of four digit, then you could do something like:
String movieYear = movieTitleAndYear.substring(movieYearIndex + 1, movieYearIndex + 5);
You need to add indexof for ")".
Code snippet:
int movieYearOpenBracesIndex = movieTitleAndYear.indexOf("(");
int movieYearCloseBracesIndex = movieTitleAndYear.indexOf(")");
String movieYear = movieTitleAndYear.substring(movieYearOpenBracesIndex + 1, movieYearCloseBracesIndex);
System.out.println(movieYear);
This will give the exact year. e.g. 1967
Your substring call currently gets a year enclosed by brackets, e.g., (1967). You can avoid this by calling the substring variant that accepts an endIndex, and just get the year's four digits:
String movieYear =
movieTitleAndYear.substring(movieYearIndex + 1, // to get rid of "("
movieYearIndex + 5 // to get rid of ")"
);

Getting the last word of a line passed to a mapper in hadoop

If I have a dataset with lines like this 199.72.81.55 - - [01/Jul/1995:00:00:01 -0400] "GET /history/apollo/ HTTP/1.0" 200 6245 and I am running a map reduce job with hadoop, how can I get the last element in each line?
I have tried all the obvious answers, such as String lastWord = test.substring(test.lastIndexOf(" ")+1); but this gives me the - character. I have tried splitting it based on a space, and getting the last element, but the last character is still a -.
Can I not expect that the data will be delivered to me line by line. In other words, can I not expect a file in the form a b c d \n e f g h\n to be delivered line by line?
And does anyone have any tips on how to get the last word in this line?
This is a snippet from my map function, where I try to get the data:
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String test = value.toString();
StringTokenizer tokenizer = new StringTokenizer(test);
//String lastWord = test.substring(test.lastIndexOf(" ")+1); <--first try
//String [] array = test.split(" ");//<--second try
//one.set(Integer.valueOf(array[8]));
int i = 0;
String candidate = null;
while (tokenizer.hasMoreTokens()) {
candidate = tokenizer.nextToken();
if (i == 3) {
//this works to get the date field
String wholeDate = candidate;
String[] dateArray = wholeDate.split(":");
String date = dateArray[0].substring(1); // get rid of '['
String hour = dateArray[1];
word.set(date + " " + hour);
} else if (i == 7) {
// <-- third try
String replySizeString = candidate;
one.set(Integer.valueOf(replySizeString)); }
}
i++;
Instead of using a StringTokenizer you could just use the String[] String.split(String regex) method to return an array of Strings for each line. Then, assuming that each line of your data has the same number of fields, separated by spaces, you can just look at that array element.
String line = value.toString();
String[] lineArray = line.split(" ");
String lastWord = lineArray[9];
Or if you know that you always want the last token you could see how long the array is and then just grab the last element.
String lastWord = lineArray[lineArray.length - 1];

Error reading data from textfile

I have an application that suppose to read data from the text file with student details (student.txt), such that I have a studentNo, StudentName, Marks etc. . .
Here is a sample of the data that's in the textfile :
20405587 "ZULU,B M" 65 67
20407388 "JUGGERNATH,N" 66 63
20408427 "KHATHI,P X" 60 60
20409821 "SINGH,T" 62 59
20410422 "NKOMO,N N" 58 60
I'm using a scanner to read from the file, here is my code so far. . .it gives me an error
try
{
BufferedReader br = new BufferedReader(new FileReader("student.txt"));
String line = br.readLine();
while (line!=null)
{
Scanner scan = new Scanner(line);
scan.useDelimiter(" ");
String dummystudent=scan.next();
int studentNo= Integer.parseInt(dummystudent);
String dummyname1 = scan.next();
String dummyname2 = scan.next();
String studentName = dummyname1+dummyname2;
String dummytest1 = scan.next();
int test1= Integer.parseInt(dummytest1);
String dummytest2 = scan.next();
int test2= Integer.parseInt(dummytest2);
tad1.setText(tad1.getText()+"Student Number: " + studentNo + '\n' + "Student Name :" + studentName );
line = br.readLine();
}
br.close();
}
catch(Exception b)
{
JOptionPane.showMessageDialog(null,b.getMessage());
}
You set the delimiter to a single space. This is the problem. next will return an empty string a few times because those lines of yours has more than one consecutive spaces.
Instead you want to say one or more spaces:
sc.useDelimiter(" +");
It's still not 100% since "ZULU,B M" has a space in the middle and "JUGGERNATH,N" doesn't, but I'll leave that to you to figure out. Maybe:
sc.useDelimiter("\"");
somewhere in the middle there.
The + has to do with regular expressions, see this for more in general and this for more Java-specific.
Your parsing seems to be overkill.
Consider using Scanner to read the line and use StringUtils.split() to parse the line.
Here is some code:
public static void main(String[] args)
{
int index = 1; // Just for printing.
for (String current : input)
{
String[] split1; // result: number, name, numbers
String[] split2;
String studentName1;
String studentName2;
String studentNumber;
String testScore1;
String testScore2;
split1 = StringUtils.split(current, '"');
studentNumber = StringUtils.trim(split1[0]);
split2 = StringUtils.split(split1[1], ',');
studentName1 = StringUtils.trim(split2[0]);
studentName2 = StringUtils.trim(split2[1]);
split2 = StringUtils.split(split1[2]); // default seperator is whitespace.
testScore1 = StringUtils.trim(split2[0]);
testScore2 = StringUtils.trim(split2[1]);
System.out.println(
index + ":" +
" Number: " + ">" + studentNumber + "" + studentName1 + "" + studentName2 + "" + testScore1 + "" + testScore2 + "
Note: StringUtils is from Apache Commons Lang
Easiest way to end would to be go line by line.
Pattern filePatten = Pattern.compile("\\s*(\\d+)\\s+(\"[^\"]+\")\\s+(\\d+)\\s+(\\d+)\\s*");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
Matcher matcher = filePattern.matcher(line);
if (matcher.matches()) {
String id = matcher.group(1);
String name = matcher.group(2);
//etc
} else {
//Warn : Fragile Regex
}
}
Each group in the regex captures a part of the line. The second group captures the name with quotes. You might want to remove it.
You should be using the delimiter "? +"?, the delimiter is a regex, and your string has multiple spaces to separate fields, you also need to take into account quotes around string fields. I'm yet to workout how to solve string fields with spaces.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#useDelimiter(java.lang.String)
Using Regex you should be able to do it using the below regex string, and select the subgroups 1-4, through a Matcher
([0-9]{8}) +"([A-Z, ]+)" +([0-9]{2}) +([0-9]{2})

Replacing a particular word in a scanned in string and concatenating using substring() in Java

I'm brand new to all of this so I am trying to write a simple bit of code that allows the user to type in text (saved as a string) and then have the code search for the position of a word, replace it and join the string back together. I.e.:
'I like foo for lunch'
foo is found at position 7
The new input is: I like Foo for lunch
Here is what I have thus far:
import java.util.Scanner;
public class FooExample
{
public static void main(String[] args)
{
/** Create a scanner to read the input from the keyboard */
Scanner sc = new Scanner (System.in);
System.out.println("Enter a line of text with foo: ");
String input = sc.nextLine();
System.out.println();
System.out.println("The string read is: " + input);
/** Use indexOf() to position of 'foo' */
int position = input.indexOf("foo");
System.out.println("Found \'foo\' at pos: " + position);
/** Replace 'foo' with 'Foo' and print the string */
input = input.substring(0, position) + "Foo";
System.out.println("The new sentence is: " + input);
The problem is occurring at the end -- where I am stumped on how to tack the rest of the sentence on to the concatenation:
input = input.substring(0, position) + "Foo";
I can get the word to be replaced but I am scratching my head over how to get the rest of the string attached on.
input = input.substring(0,position) + "Foo" + input.substring(position+3 , input.length());
or simply you can use replace method.
input = input.replace("foo", "Foo");
Slight update to what Achintya posted, to take into account you don't want to include "foo" again:
input = input.substring(0, position) + "Foo" + input.substring(position + 3 , input.length());
This may be overkill, but if you are looking for words in sentences, you could easily use StringTokenizer
StringTokenizer st = new StringTokenizer(input);
String output="";
String temp = "";
while (st.hasMoreElements()) {
temp = st.nextElement();
if(temp.equals("foo"))
output+=" "+"Foo";
else
output +=" "+temp;
}

Categories