JAVA- Splitting string into tokens but fails with error [duplicate] - java

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
I am trying to read from a text file that has 20 lines and supposed to store them into an array and assign them a variable, firstname lastname and grade. Because I have to output them as last name, firstname and grade, I decided to use tokens but somehow I get this error: java.lang.ArrayIndexOutOfBoundsException: 1
public static void main(String[] args) throws IOException {
int numberOfLines = 20;
studentClass[] studentObject = new studentClass[numberOfLines];
readStudentData(studentObject);
}
public static void readStudentData(studentClass[] studentObject)throws {
//create FileReader and BufferedReader to read and store data
FileReader fr = new FileReader("/Volumes/PERS/Data.txt");
BufferedReader br = new BufferedReader (fr);
String line = null;
int i = 0;
//create array to store data for firstname, lastname, and score
while ((line = br.readLine()) != null){
String[] stuArray = line.split(" ");
String stuFName = stuArray[0];
String stuLName = stuArray[1];
int score = Integer.parseInt(stuArray[2]);
studentObject[i] = new studentClass (stuFName, stuLName, score);
i++;
}
br.close();
for(i = 0; i<studentObject.length; i++){
System.out.print(studentObject[i].getStudentFName());
}
}
The error that I get is specifically this line:
String stuLName = stuArray[1];
Here is the text file:
Duckey Donald 85
Goof Goofy 89
Brave Balto 93
Snow Smitn 93
Alice Wonderful 89
Samina Akthar 85
Simba Green 95
Donald Egger 90
Brown Deer 86
Johny Jackson 95
Greg Gupta 75
Samuel Happy 80
Danny Arora 80
Sleepy June 70
Amy Cheng 83
Shelly Malik 95
Chelsea Tomek 95
Angela Clodfelter 95
Allison Nields 95
Lance Norman 88

I think at the last line of your file you have white spaces. make sure last line hast no white space like space or tab.

First, next time you should include the import and output also in your code
for us to easy to fix it, and one more thing, the Class name should be
StudentClass, not studentClass, it have to me different with methods.
Second, I can't test your code without your studentClass ... So I only can guess it:
Consider 1: The text file have one more line (with white space) >> Impossible because String test = " "; test.split(" ")[0] == null;
Consider 2: Your text file has error, to test it, I suggest you to add
System.out.println(line + ".") after while ((line = br.readLine()) != null){
to test it, believe me, you will receive the last line because it's bloged;

Related

How to access each element after a split

I am trying to read from a text file and split it into three separate categories. ID, address, and weight. However, whenever I try to access the address and weight I have an error. Does anyone see the problem?
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;
class Project1
{
public static void main(String[] args)throws Exception
{
List<String> list = new ArrayList<String>();
List<String> packages = new ArrayList<String>();
List<String> addresses = new ArrayList<String>();
List<String> weights = new ArrayList<String>();
//Provide the file path
File file = new File(args[0]);
//Reads the file
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while((str = br.readLine()) != null)
{
if(str.trim().length() > 0)
{
//System.out.println(str);
//Splits the string by commas and trims whitespace
String[] result = str.trim().split("\\s*,\\s*", 3);
packages.add(result[0]);
//ERROR: Doesn't know what result[1] or result[2] is.
//addresses.add(result[1]);
//weights.add(result[2]);
System.out.println(result[0]);
//System.out.println(result[1]);
//System.out.println(result[2]);
}
}
for(int i = 0; i < packages.size(); i++)
{
System.out.println(packages.get(i));
}
}
}
Here is the text file (The format is intentional):
,123-ABC-4567, 15 W. 15th St., 50.1
456-BgT-79876, 22 Broadway, 24
QAZ-456-QWER, 100 East 20th Street, 50
Q2Z-457-QWER, 200 East 20th Street, 49
678-FGH-9845 ,, 45 5th Ave,, 12.2,
678-FGH-9846,45 5th Ave,12.2
123-A BC-9999, 46 Foo Bar, 220.0
347-poy-3465, 101 B'way,24
,123-FBC-4567, 15 West 15th St., 50.1
678-FGH-8465 45 5th Ave 12.2
Seeing the pattern in your data, where some lines start with an unneeded comma, and some lines having multiple commas as delimiter and one line not even having any comma delimiter and instead space as delimiter, you will have to use a regex that handles all these behaviors. You can use this regex which does it all for your data and captures appropriately.
([\w- ]+?)[ ,]+([\w .']+)[ ,]+([\d.]+)
Here is the explanation for above regex,
([\w- ]+?) - Captures ID data which consists of word characters hyphen and space and places it in group1
[ ,]+ - This acts as a delimiter where it can be one or more space or comma
([\w .']+) - This captures address data which consists of word characters, space and . and places it in group2
[ ,]+ - Again the delimiter as described above
([\d.]+) - This captures the weight data which consists of numbers and . and places it in group3
Demo
Here is the modified Java code you can use. I've removed some of your variable declarations which you can have them back as needed. This code prints all the information after capturing the way you wanted using Matcher object.
Pattern p = Pattern.compile("([\\w- ]+?)[ ,]+([\\w .']+)[ ,]+([\\d.]+)");
// Reads the file
try (BufferedReader br = new BufferedReader(new FileReader("data1.txt"))) {
String str;
while ((str = br.readLine()) != null) {
Matcher m = p.matcher(str);
if (m.matches()) {
System.out.println(String.format("Id: %s, Address: %s, Weight: %s",
new Object[] { m.group(1), m.group(2), m.group(3) }));
}
}
}
Prints,
Id: 456-BgT-79876, Address: 22 Broadway, Weight: 24
Id: QAZ-456-QWER, Address: 100 East 20th Street, Weight: 50
Id: Q2Z-457-QWER, Address: 200 East 20th Street, Weight: 49
Id: 678-FGH-9845, Address: 45 5th Ave, Weight: 12.2
Id: 678-FGH-9846, Address: 45 5th Ave, Weight: 12.2
Id: 123-A BC-9999, Address: 46 Foo Bar, Weight: 220.0
Id: 347-poy-3465, Address: 101 B'way, Weight: 24
Id: 678-FGH-8465, Address: 45 5th Ave, Weight: 12.2
Let me know if this works for you and if you have any query further.
The last line only contains one token. So split will only return an array with one element.
A minimal reproducing example:
import java.io.*;
class Project1 {
public static void main(String[] args) throws Exception {
//Provide the file path
File file = new File(args[0]);
//Reads the file
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while ((str = br.readLine()) != null) {
if (str.trim().length() > 0) {
String[] result = str.trim().split("\\s*,\\s*", 3);
System.out.println(result[1]);
}
}
}
}
With this input file:
678-FGH-8465 45 5th Ave 12.2
The output looks like this:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Project1.main(a.java:22)
Process finished with exit code 1
So you will have to decide, what your program should do in such cases. You might ignore those lines, print an error, or only add the first token in one of your lists.
you can add following code in your code
if (result.length > 0) {
packages.add(result[0]);
}
if (result.length > 1) {
addresses.add(result[1]);
}
if (result.length > 2) {
weights.add(result[2]);
}

Java: Token rearrangement and character removal with text file

I am trying to take a text file which has a list of peoples first and last names with age and rearrange it so the console output would go from 46 Richman, Mary A. to Mary A. Richman 46. However, in my attempt to do so I have ran into issues (shown below) and I don't understand exactly why they're occurring (it was much worse earlier).
I'd really appreciate the assistance!
Text File:
75 Fresco, Al
67 Dwyer, Barb
55 Turner, Paige
108 Peace, Warren
46 Richman, Mary A.
37 Ware, Crystal
83 Carr, Dusty
15 Sledd, Bob
64 Sutton, Oliver
70 Mellow, Marsha
29 Case, Justin
35 Time, Justin
8 Shorts, Jim
20 Morris, Hugh
25 Vader, Ella
76 Bird, Earl E.
My Code:
import java.io.*;
import java.util.*;
public class Ex2 {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("people.txt"));
while (input.hasNext()) { // Input == people.txt
String line = input.next().replace(",", "");
String firstName = input.next();
String lastName = input.next();
int age = input.nextInt();
System.out.println(firstName + lastName + age);
}
}
}
Bad Console Output: (How is it throwing an Unknown Source Error?)
Fresco,Al67
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at Ex2.main(Ex2.java:11)
Target Console Output:
Al Fresco 75
Barb Dwyer 67
Paige Turner 55
Warren Peace 108
Mary A. Richman 46
Crystal Ware 37
Dusty Carr 83
Bob Sledd 15
Oliver Sutton 64
Marsha Mellow 70
Justin Case 29
Justin Time 35
Jim Shorts 8
Hugh Morris 20
Ella Vader 25
Earl E. Bird 76
This will make sure the first name includes the middle initial
while (input.hasNext())
{
String[] line = input.nextLine().replace(",", "").split("\\s+");
String age = line[0];
String lastName = line[1];
String firstName = "";
//take the rest of the input and add it to the last name
for(int i = 2; 2 < line.length && i < line.length; i++)
firstName += line[i] + " ";
System.out.println(firstName + lastName + " " + age);
}
You can avoid the issue and simplify the logic by actually reading with input.nextLine() as shown in the below code with comments:
while (input.hasNextLine()) {
String line = input.nextLine();//read next line
line = line.replace(",", "");//replace ,
line = line.replace(".", "");//replace .
String[] data = line.split(" ");//split with space and collect to array
//now, write the output derived from the split array
System.out.println(data[2] + " " + data[1] + " " + data[0]);
}

Capture each data in a string from a flat file txt?

I have a question, I happen to read a flat arhivo few codes, but the query is how to capture each data organized, I mean that there is always values ​​in some columns, if they are empty I'm going to save as NULL on an object.
Input:
19150526 1 7 1
19400119 2 20 1 1
19580122 2 20 9 1
19600309 1 20 7 1
19570310 2 20 5 1
19401215 1 10 1 1
19650902 2 20 0 1
19510924 1 20 3 1
19351118 2 30 1
19560118 1 20 0 1
19371108 2 7 1
19650315 1 30 6 1
19601217 2 30 4 1
Code Java:
FileInputStream fstream = new FileInputStream("C:\\sppadron.txt");
DataInputStream entrada = new DataInputStream(fstream);
BufferedReader buffer = new BufferedReader(new InputStreamReader(entrada));
String strLinea;
List<Sppadron> listSppadron = new ArrayList<Sppadron>();
while ((strLinea = buffer.readLine()) != null){
Sppadron spadron= new Sppadron();
spadron.setSpNac(strLinea.substring(143, 152).trim());
spadron.setSpSex(strLinea.substring(152, 154).trim());
spadron.setSpGri(strLinea.substring(154, 157).trim());
spadron.setSpSec(strLinea.substring(157, 158).trim());
spadron.setSpDoc(strLinea.substring(158, strLinea.length()).trim());
listSppadron.add(spadron);
}
entrada.close();
Originally I had the idea of doing it this way, but in practice happens is that the position of each string is not fixed as it looks, so I happened to use a split (), but there are different spaces between each data and the latest to use a replaceAll (), but leaves all the data together, is there any way to separate each data regardless of the spacing between each data.
Whereas each row penultimate data can come see it empty as the input data file that printable.
try following
strLinea = strLinea.trim().replaceAll("\\s"," ");
String stArr[] = strLinea.split(" ");
then use strArr for further as per your requirement.
if you want it as list you can use Arrays.asList(strArr);
try this way..
replace wherever you see contiguous spaces with a single space
strLinea.replaceAll("\\s+"," ")
Then do your splits
OR
something like
String[] tokensVal = strLinea.split("\\s+");
You're on the right lines using a StringBuffer to read the file line by line. Once you have a line in the buffer, try using the StringTokenizer class to pull out each field. StringTokenizer will by default split on white space and you can iterate through the columns.
consider the below:
public static void main(String[] args) {
String s = "hello\t\tworld some spaces \tbetween here";
StringTokenizer st = new StringTokenizer(s);
while(st.hasMoreTokens())
{
System.out.println(st.nextToken());
}
}
This will output:
hello
world
some
spaces
between
here
You could base your solution on this. Maybe have a builder pattern that can return the objects you need given the current line..

Need help reading text file into Object

I have created a Person class, with parameters firstname, lastname, and year. I need to figure out how to read input from a text file and create an Array of Persons. Here is what I am trying, based on different sources I pooled from the web.
String name = "People.txt";
Person[] people = new ArrayList<Person>();
BufferedReader br = new BufferedReader(new FileReader(name));
String line = br.readLine();
while(line != null)
{
people.add(line);
line = br.readLine();
}
But of course, this isn't working. I doubt its even close to being correct, so I was wondering if you guys have any advice.
Also, the constructor for my Person class is as follows:
public Person(String firstName, String lastName, int age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
The error reads,
`SortingImplementation.java:15: incompatible types
found : java.util.ArrayList<Person>
required: Person[]
Person[] people = new ArrayList<Person>();
^
SortingImplementation.java:20: cannot find symbol
symbol : method add(java.lang.String)
location: class Person[]
people.add(line);
^
Note: SortingMethod.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 errors
`
Text file is
Larry Kim 45
Bob Stuart 51
Nancy Davis 38
John Doe 49
Henry Miles 23
Albert Lee 36
Mary Wing 43
Tony Rich 55
Ally Sneetch 19
Carrie Chrome 77
David Abkenzy 41
Young Old 18
Snow White 70
George Herald 60
Mike Bush 22
Peter Paul 33
Peter Pan 44
Mary Paul 25
Ray Romano 55
Well, sweet. You guys are awesome, maybe I'll get to sleep tonight. Been up for literally two days straight trying to get this done, starting to hallucinate. One last problem I am having, and I am sure it is something simple, but I am getting this error.
SortingImplementation.java:15: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
BufferedReader br = new BufferedReader(new FileReader("People.txt"));
^
SortingImplementation.java:16: unreported exception java.io.IOException; must be caught or declared to be thrown
String line = br.readLine();
I think it might just have to do with the way I am instantiating, or maybe I don't have the proper header files imported. Here's what I have imported.
import javax.swing.JOptionPane;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.io.*;
import java.nio.*;
Do you guys see anything that might be missing?
You have two options.
Without changing the Person class, after reading the line, you can parse the data into the firstName, lastName, and age, and send these arguments to the constructor.
You can add a constructor to Person that expects a single, unparsed String argument and does all the parsing within the constructor and assigns the initializes the variables from there.
For details on how to do either option, you'd have to show us what the text file looks like exactly.
But currently, your problem is that you're trying to add a String object to an ArrayList of Person objects.
You need to do this:
people.add(new Person(/*constructor arguments*/));
Now that you've updated to include the file format, try something like this:
while(line != null) {
String[] lineParts = line.split("\\s+");
people.add(new Person(lineParts[0],lineParts[1],parseInt(lineParts[2]));
line = br.readLine();
}
Doing via an additional Person constructor isn't much different.
In your Person class, add this constructor:
public Person(String s) {
String[] parts = s.split("\\s+");
this(parts[0], parts[1], parseInt(parts[2]));
}
Then in main, make your while loop look like this:
while(line != null) {
people.add(new Person(line));
line = br.readLine();
}
You can't just add a line String and expect it to magically transform into a Person. You need to split each line into separate Strings then create a person from those String
Person[] people = new ArrayList<Person>();
BufferedReader br = new BufferedReader(new FileReader(name));
String line = br.readLine();
while(line != null)
{
people.add(line);
line = br.readLine();
}
You need to do something like this, Note the change from array to ArrayList<Person>
ArrayList<Person> people = new ArrayList<Person>(); // Notice change here
BufferedReader br = new BufferedReader(new FileReader(name));
String line;
while((line = br.nextLine()) != null)
{
String[] tokens = line.split("\\s+");
String firstName = tokens[0];
String lastName = tokens[1];
int age = Integer.parseInt(tokens[2]); // parse String to int
people.add(new Person(firstName, lastName, age));
}
This is assuming the input text is formatted as follows
FirstName LastName Age
Also, make sure to wrap everything in a try/catch block, or have the method throws IOException;

parsing csv by "," and " "

I have file with data format as
userid, friend id, books id, cd id
1, 11 12 14 12, 223 256 333 234 222, 22
2, 78 22, 22 66 11 29, 76 455
3, 123 22 11 234 198 122 881, 34 12 98 64, 22
where I need to use only user id and cd id, But I am unable to separate these fields.
My Java code as below.
BufferedReader in = new BufferedReader(new FileReader("CSV_test.txt"));
BufferedWriter ou =new BufferedWriter(new FileWriter("users.csv"));
String str;
str = in.readLine();
while ((str = in.readLine()) != null) {
String[] ar = str.split(",");
String[] ar1 = ar[1].split("");
ou.write(ar[0]);
ou.write(",");
ou.write(ar1[1]);
ou.newLine(); }
in.close();
ou.close();
}
Is there any issue with this?
Surely you want
String[] ar = str.split(",");
String user = ar[0].trim();
String cd = ar[3].trim();
Note that I'm trimming to remove leading/trailing spaces.
You could split using ", " (note the trailing space) and that would remove the need to further trim(). It does make some assumptions however as to how your fields are separated (commas ? commas-and-spaces?) and perhaps it's worth investigating a CSV library.
No need to reinvent the wheel. While CSV parsing is fairly simple, there are things that might be a little bit complicated (such as escaping the separator in field values). Existing libraries can do this for you, such as OpenCSV or CsvJdbc

Categories

Resources