Java BufferReader To array stored by lines - java

Given a list of polynoms I need to store them on different arrays depending on the row.
Example:
5 -4 2 0 -2 3 0 3 -17 int[] a = {-17, 3, 0, 3, -2, 0, 2, -4, 5}
4 -2 0 1 int[] b = {1, 0, -2, 4}
First line I need to put on the array a[], and the second one on array b[]
Tried something like this:
File file=new File("Pol.txt");
BufferedReader b=new BufferedReader(new InputStreamReader(new FileInputStream(file)));
Pattern delimiters=Pattern.compile(System.getProperty("line.separator")+"|\\s");
String line=b.readLine();

First, you will want to make sure that any file reading objects are always properly cleaned up. A try-with-resources block is your best bet, or otherwise a try finally block.
try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
new FileInputStream(file))) {
//code using bufferedReader goes here.
}
You should not need to use the Pattern class here. It's a simple case of reading a line and using the String.split method. e.g.
String line = bufferedReader.readLine();
//if (line == null) throw an exception
String[] splitLine = line.split("\\s+");
Now the splitLine variable will contain an array of Strings, which is each of the elements from the original line, as separated by spaces. The split method takes a String which is the regular expression representing the 'delimiter' of your values. For more information on regular expressions in Java, try this. The "\\s+" represents any whitespace character or characters These can be 'parsed' to int values using the Integer.parseInt method, like this:
int[] a = new int[splitLine.length];
for(int i = 1; i <= splitLine.length; i++) {
int parsed = Integer.parseInt(splitLine[i]);
a[splitLine.length - i] = parsed;
}
The parseInt method may throw a NumberFormatException, for example if you give it the String "Hello world". You can either catch that or let it be thrown.

Related

How do I read txt file if I have multiple attributes?

I am trying to get a class to read my txt file with a few lines, for example:
Facial Lotion, 1 , 2, 0.1
Moisturiser Lotion, 2, 3, 0.2
Toner Lotion, 3, 4, 0.3
Aloe Vera Lotion, 4, 5, 0.4
I created a class call Lotion with attributes name(string), productNo(int), productRating(int), and productDiscount(double, and I create another class call ListOfLotion and add in an arraylist of Lotion.
my problem is how do i get my ListOfLotion class to use the values in txt file and put it in my arraylist.
I tried to use indexOf for name till the next one but i got error,
java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 17
also is there anyway i could separate all four value and make sure they are store properly for example, Facial Lotion is store as the name and 1 is store as prodcuctNo.
public void addListOfLotion(){
ArrayList<Lotion> lotion = new ArrayList<Lotion>();
Scanner scanner = new Scanner("Desktop/Lotion.txt");
while(scanner.hasNext()){
String readLine = scanner.nextLine();
int indexProductNo = readLine.indexOf(',');
int indexOfProductRating = readLine.indexOf(',');
double indexOfProductDiscount = readLine.indexOf(',');
lotion.add(new Lotion(readLine.substring(0, indexOfProductNo),0,0,0));
}scanner.close();
}
Got this error as result:
java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 17
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
at java.base/java.lang.String.substring(String.java:1874)
at ListOfVenues.addListOfLotion(ListOfLotion.java:42)
Is it beccause I put readLine,indexOf(',') as every readLine, it just stop at the first ','? Anyway I could effectively let java know that between this and this index is for name, and between this and this index is for productNo?
thanks guys really appreciate it.
Since the lines are comma-separated lists you could use split() to split the line into the single variables.
Another thing to consider is that Scanner("file.txt") doesn't read the indicated text file but just the given String. You have to create a File object first.
File input = new File("Desktop/Lotion.txt");
Scanner scanner;
scanner = new Scanner(input);
while(scanner.hasNext()){
String readLine = scanner.nextLine();
String[] strArray = readLine.split(",");
int indexOfProductNo = Integer.parseInt(strArray[1].trim());
int indexOfProductRating = Integer.parseInt(strArray[2].trim());
double indexOfProductDiscount = Double.parseDouble(strArray[3].trim());
lotion.add(new Lotion(strArray[0],indexOfProductNo,indexOfProductRating,indexOfProductDiscount));
}
You could use a regex (Demo):
([\w\s]+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+(?:\.\d+))
Which you could define as a constant in your class:
private static final Pattern LOTION_ENTRY =
Pattern.compile("([\\w\\s]+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+(?:\\.\\d+))");
Then you can just create a Matcher for every entry and extract the groups:
Matcher matcher = LOTION_ENTRY.matcher(readLine);
if(matcher.matches()) {
String name = matcher.group(1);
int no = Integer.parseInt(matcher.group(2));
int rating = Integer.parseInt(matcher.group(3));
double discount = Double.parseDouble(matcher.group(4));
// do something
} else {
// line doesn't match pattern, throw error or log
}
A note though: the parseInt() and parseDouble can throw a NumberFormatException if the input is not valid. So you'd have to catch those and act accordingly.

How do I convert a String to an String Array? [duplicate]

This question already has answers here:
How do I convert a String to an int in Java?
(47 answers)
Closed 7 years ago.
I'm reading from a file using Scanner, and the text contains the following.
[8, 3, 8, 2, 3, 4, 4, 4, 5, 8]
This was originally an integer Array that I had to convert to a String to be able to write in the file. Now, I need to be able to read the file back into java, but I need to be able to add the individual numbers together, so I need to get this String back into an array. Any help? Here's what I have:
File f = new File("testfile.txt");
try{
FileWriter fw = new FileWriter(f);
fw.write(Arrays.toString(array1));
fw.close();
} catch(Exception ex){
//Exception Ignored
}
Scanner file = new Scanner(f);
System.out.println(file.nextLine());
This prints out the list of numbers, but in a string. I need to access the integers in an array in order to add them up. This is my first time posting, let me know if I messed anything up.
You can use String#substring to remove the square brackets, String#split to split the String into an array, String#trim to remove the whitespace, and Integer#parseInt to convert the Strings into int values.
In Java 8 you can use the Stream API for this:
int[] values = Arrays.stream(string.substring(1, string.length() - 1)
.split(","))
.mapToInt(string -> Integer.parseInt(string.trim()))
.toArray();
For summing it, you can use the IntStream#sum method instead of converting it to an array at the end.
You don't need to read the String back in an Array, just use Regex
public static void main(String[] args) throws Exception {
String data = "[8, 3, 8, 2, 3, 4, 41, 4, 5, 8]";
// The "\\d+" gets the digits out of the String
Matcher matcher = Pattern.compile("\\d+").matcher(data);
int sum = 0;
while(matcher.find()) {
sum += Integer.parseInt(matcher.group());
}
System.out.println(sum);
}
Results:
86
List<Integer> ints = new ArrayList<>();
String original = "[8, 3, 8, 2, 3, 4, 4, 4, 5, 8]";
String[] splitted = original.replaceAll("[\\[\\] ]", "").split(",");
for(String s : splitted) {
ints.add(Integer.valueOf(s));
}

How to read an empty set from a text file in Java

I have 3 String fields per line within my text file. There are 4 lines in total. The first 2 fields (field[0] and field[1]) are already filled in but field 3 (field[2]) is yet to be generated so it shall remain empty. Is there any way I can read in this text file line by line without getting a java.lang.ArrayIndexOutOfBoundsException: 1 error? I have included my code used for reading in the file.
import java.io.*;
public class PassGen {
public static void main(String args[]) throws Exception{
BufferedReader inKb = new BufferedReader(new InputStreamReader(System.in));
BufferedReader inF = new BufferedReader(new FileReader(new File("students.txt")));
String line = inF.readLine();
int cnt = 0;
Student pupil[] = new Student[6];
while(line != null) {
String field[] = line.split("//s");
pupil[cnt] = new Student(field[0], field[1], field[2]);
cnt++;
inF.readLine();
}
}
}
You can simply add a check on the number of fields:
if(field.length > 2) {
pupil[cnt] = new Student(field[0], field[1], field[2]);
} else {
pupil[cnt] = new Student(field[0], field[1], null);
}
Alternatively, you can use the overloaded split method that takes a limit parameter and set that to -1 to include the empty field. From the documentation of String#split(String regex, int limit):
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.
Note that you need to use \\s instead of //s for the whitespace regex (this needs to be corrected either way).
String field[] = line.split("\\s", -1);
I think you problem lies in the way you are managing your data, but you can have something like this to read from any array and not getting any exceptions:
public static String getIfExists(final String[] values, final int position) {
return (values != null) && (values.length > position) ? values[position] : null;
}
Then you can fill every field like new Student(getIfExists(field, 0), getIfExists(field, 1), getIfExists(field, 2));
Of course you can optimize this a little bit more...but that would make the trick without having to think on how many fields you might get in the future or having a lot of if/case conditions.

Cannot get a Substring of a substring

I'm trying to parse a String from a file that looks something like this:
Mark Henry, Tiger Woods, James the Golfer, Bob,
3, 4, 5, 1,
1, 2, 3, 5,
6, 2, 1, 4,
For ease of use, I'd like to split off the first line of the String, because it will be the only one that cannot be converted into integer values (the rest will be stored in a double array of integers[line][value]);
I tried to use String.split("\\\n") to divide out each line into its own String, which works. However, I am unable to divide the new strings into substrings with String.split("\\,"). I am not sure what is going on:
String[] firstsplit = fileOne.split("\\\n");
System.out.println("file split into " + firstsplit.length + " parts");
for (int i = 0; i < firstsplit.length; i++){
System.out.println(firstsplit[i]); // prints values to verify it works
}
String firstLine = firstsplit[0];
String[] secondSplit = firstLine.split("\\,");
System.out.println(secondSplit[0]); // prints nothing for some reason
I've tried a variety of different things with this, and nothing seems to work (copying over to a new String is an attempt to get it to work even). Any suggestions?
EDIT: I have changed it to String.split(",") and also tried String.split(", ") but I still get nothing to print afterwards.
It occurs to me now that maybe the first location is a blank one....after testing I found this to be true and everything works for firstsplit[1];
You're trying to split \\,, which translates to the actual value \,. You want to escape only ,.
Comma , doesn't need \ before it as it isn't a special character. Try using , instead of \\,, which is translated to \, (not only a comma, also a backslash).
Not only do you not need to escape a comma, but you also don't need three backslashes for the newline character:
String[] firstSplit = fileOne.split("\n");
That will work just fine. I tested your code with the string you specified, and it actually worked just fine, and it also worked just fine splitting without the extraneous escapes...
Have you actually tested it with the String data you provided in the question, or perhaps is the actual data something else. I was worried about the carriage return (\r\n in e.g. Windows files), but that didn't matter in my test, either. If you can scrub the String data you're actually parsing, and provide a sample output of the original String (fileOne), that would help significantly.
You could just load the file into a list of lines:
fin = new FileInputStream(filename);
bin = new BufferedReader(new InputStreamReader(fin));
String line = null;
List<String> lines = new ArrayList<>();
while (( line = bin.readLine()) != null ) {
lines.add( line );
}
fin.close();
Of course you have to include this stuff into some try catch block which fits into your exception handling. Then parse the lines starting with the second one like this:
for ( int i = 1; i < lines.size(); i++ ) {
String[] values = lines.get( i ).split( "," );
}

Reading integers from a file separated by space in java

Input file containing integers will be like this:
5 2 3 5
2 4 23 4 5 6 4
So how would I read the first line, separate it by space and add these numbers to Arraylist1. Then read the second line, separate it by space and add the numbers to ArrayList2 and so on. (So Arraylist1 will contain [5,2,3,5] etc)
FileInputStream fstream = new FileInputStream("file.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String data;
while ((data = br.readLine()) != null) {
//How can I do what I described above here?
}
Homework?
You can use this:
String[] tmp = data.split(" "); //Split space
for(String s: tmp)
myArrayList.add(s);
Or you have a look at the Scanner class.
Consider using a StringTokenizer
Some help : String tokenizer
StringTokenizer st = new StringTokenizer(in, "=;");
while(st.hasMoreTokens()) {
String key = st.nextToken();
String val = st.nextToken();
System.out.println(key + "\t" + val);
}
You can get a standard array out of data.split("\\s+");, which will give you int[]. You'll need something extra to throw different lines into different lists.
After I tried the answer provided by HectorLector, it didn't work in some specific situation. So, here is mine:
String[] tmp = data.split("\\s+");
This uses Regular Expression
what you would require is something like an ArrayList of ArrayList. You can use the data.split("\\s+"); function in java to get all the elements in a single line in a String array and then put these elements into the inner ArrayList of the ArrayList of ArrayLists.
and for the next line you can move to the next element of the outer ArrayList and so on.

Categories