Error reading data from textfile - java

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

Related

Java string manipulation for validity

Say for instance I have this string:
"His name is Justin Hoffman"
and need to check if it is a valid name:
In order for this to return true I need to make sure I have "His name" before "is" and I need "Justin Hoffman" after the "is" how can I check to see if I have the correct substring before "is" and the correct one after "is"
String sentence = "His name is Justin Hoffman";
String[] splitSentence = sentence.split(" is ");
String first = splitSentence[0]; // His name
String second = splitSentence[1]; // Justin Hoffman
boolean isTrue = (first.equals("His name") && second.equals("Justin Hoffman"));
String input = "His name is Justin Hoffman";
String requiredFirstName = "His name";
String requiredLastName = "Justin Hoffman";
String delimiter = " is ";
// Example 1
if (input.equals(requiredFirstName + delimiter + requiredLastName))
{
System.out.println("The input is OK");
}
// Example 2
int posi = input.indexOf(delimiter);
if (posi > 0) // found
{
String leftPart = input.substring(0, posi);
String rightpart = input.substring(posi + delimiter.length());
if (requiredFirstName.equals(leftPart) && requiredLastName.equals(rightpart))
{
System.out.println("The input is OK");
}
}
// Example 3
String[] parts = input.split(delimiter);
if (requiredFirstName.equals(parts[0]) && requiredLastName.equals(parts[1]))
{
System.out.println("The input is OK");
}
The second example is possibly the fastest one because it does not produce temporary strings. The third example is the slowest one. Be careful with special character in the delimiter because the split() function interprets the argument as a regular expression.

How to split a text that contains String and Int and store into an ArrayList?

So basically I have a java program that reads a txt file using BufferedReader.
The text file contains all the information about the movies. The first column is the code, the second is the title and the third is the rating.
e.g
1 Titanic 44
34 Avengers 60
2 The Lord of the Rings 100
So 1 is the code, Titanic is the title and 44 is the rating etc.
My problem is that I have made a class Movie(int code, String title, int rating)
and I want to store all the informations in there but I can't figure out how to split the text. split(" ") doesn't seem like it would handle the case where a title has embedded spaces (e.g The Lord of the Rings).
What I really need is the ability to strip off the first and last fields based on space as a separator, and treat all other interior spaces as part of the title, not as separators.
You are correct, split that you already tried is inappropriate. Based on the pattern you are showing, the delimiters seem to be the first and the last space in each line and everything between them is the title. I recommend to find the index of these spaces and use substring().
Eg:
String text = "2 The Lord of the Rings 100";
int firstSpace = text.indexOf(' ');
int lastSpace = text.lastIndexOf(' ');
String codeText = text.substring(0, firstSpace);
String title = text.substring(firstSpace, lastSpace);
String ratingText = text.substring(lastSpace);
You can use split(" ")
Use
String[] foo = split(" ")
The first element in foo will be the first integer. Convert that to an integer type. Then step through the remaining elements and append them into one string, except for the last element in foo, which will be your last integer and you can convert that to an integer type.
You can try this as you mentioned I can't use split(" ") because some titles (e.g The Lord of the Rings) has spaces between the title.
String str = "2 The Lord of the Rings 100";
String[] arr = str.split("\\s+");
List<String> list = Arrays.asList(arr);
Get the data for arr
String code = arr[0];
String rate = arr[arr.length-1];
String title = "";
for (int i = 1; i < arr.length-1; i++) {
title += arr[i]+" ";
}
Run the code
System.out.println("code = " + code);
System.out.println("rate = " + rate);
System.out.println("title = " + title);
And it is the result:
code = 2
rate = 100
title = The Lord of the Rings
May this help you...
See Regexp and Matcher classes with pattern : (\d*)\s(.*)\s(\d*)
EDIT : Example
#Test
public void testRegExp(){
String text = "2 The Lord of the Rings 100";
String patternString = "(\\d*)\\s(.*)\\s(\\d*)";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println("CODE : " + matcher.group(1));
System.out.println("TITLE : " + matcher.group(2));
System.out.println("RATE : " + matcher.group(3));
}
}
String line = "1 Titanic 44";
int code = Integer.valueOf(line.split(" ")[0]);
String title = line.split(" ")[1];
int rank = Integer.valueOf(line.split(" ")[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;
}

Cut ':' && " " from a String with a tokenizer

right now I am a little bit confused. I want to manipulate this string with a tokenizer:
Bob:23456:12345 Carl:09876:54321
However, I use a Tokenizer, but when I try:
String signature1 = tok.nextToken(":");
tok.nextToken(" ")
I get:
12345 Carl
However I want to have the first int and the second int into a var.
Any ideas?
You have two different patterns, maybe you should handle both separated.
Fist you should split the space separated values. Only use the string split(" "). That will return a String[].
Then for each String use tokenizer.
I believe will works.
Code:
String input = "Bob:23456:12345 Carl:09876:54321";
String[] words = input.split(" ")
for (String word : words) {
String[] token = each.split(":");
String name = token[0];
int value0 = Integer.parseInt(token[1]);
int value1 = Integer.parseInt(token[2]);
}
Following code should do:
String input = "Bob:23456:12345 Carl:09876:54321";
StringTokenizer st = new StringTokenizer(input, ": ");
while(st.hasMoreTokens())
{
String name = st.nextToken();
String val1 = st.nextToken();
String val2 = st.nextToken();
}
Seeing as you have multiple patterns, you cannot handle them with only one tokenizer.
You need to first split it based on whitespace, then split based on the colon.
Something like this should help:
String[] s = "Bob:23456:12345 Carl:09876:54321".split(" ");
System.out.println(Arrays.toString(s ));
String[] so = s[0].split(":", 2);
System.out.println(Arrays.toString(so));
And you'd get this:
[Bob:23456:12345, Carl:09876:54321]
[Bob, 23456:12345]
If you must use tokeniser then I tink you need to use it twice
String str = "Bob:23456:12345 Carl:09876:54321";
StringTokenizer spaceTokenizer = new StringTokenizer(str, " ");
while (spaceTokenizer.hasMoreTokens()) {
StringTokenizer colonTokenizer = new StringTokenizer(spaceTokenizer.nextToken(), ":");
colonTokenizer.nextToken();//to igore Bob and Carl
while (colonTokenizer.hasMoreTokens()) {
System.out.println(colonTokenizer.nextToken());
}
}
outputs
23456
12345
09876
54321
Personally though I would not use tokenizer here and use Claudio's answer which splits the strings.

Reading Strings from lines in Java

I have a txt file formatted like:
Name 'Paul' 9-years old
How can I get from a "readline":
String the_name="Paul"
and
int the_age=9
in Java, discarding all the rest?
I have:
...
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
//put the name value in the_name
//put age value in the_age
}
...
Please suggest, thanks.
As you're using BufferedReader and everything is on the one line, you would have to split it to extract the data. Some additional formatting is then required to remove the quotes & extract the year part of age. No need for any fancy regex:
String[] strings = line.split(" ");
if (strings.length >= 3) {
String the_name= strings[1].replace("'", "");
String the_age = strings[2].substring(0, strings[2].indexOf("-"));
}
I notice you have this functionality in a while loop. For this to work, make sure that every line keeps the format:
text 'Name' digit-any other text
^^ ^^ ^
Important chars are
Spaces: min of 3 tokens needed for split array
Single quotes
- Hyphen character
use java.util.regex.Pattern:
Pattern pattern = Pattern.compile("Name '(.*)' (\d*)-years old");
for (String line : lines) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
String theName = matcher.group(1);
int theAge = Integer.parseInt(matcher.group(2));
}
}
You can use the String.substring, String.indexOf, String.lastIndexOf, and Integer.parseInt methods as follows:
String line = "Name 'Paul' 9-years old";
String theName = line.substring(line.indexOf("'") + 1, line.lastIndexOf("'"));
String ageStr = line.substring(line.lastIndexOf("' ") + 2, line.indexOf("-years"));
int theAge = Integer.parseInt(ageStr);
System.out.println(theName + " " + theAge);
Output:
Paul 9

Categories