java splitting a string by line \n not working - java

So I have a string which is from a text file, essentially the text file is just 5 lines which read:
x=1
y=15
z=128
topx=100
leftx=150
label= this is a test
I am able to get the split to work once which separates via the '=' sign, but when I try to split the string again by \n nothing works, I have tried using "\r?\n", line.Separator etc. but the string value always stays the same, basically the 5 lines without the characters before the = sign. How would I pull out the individual lines to assign variables to?
Here is the code I have, basically the println is to try and see if I can get the first value '1' to list separate from the rest of the lines.
public static void main(String[] a) {
15 draw d = new draw();
16 Read r = new Read();
17 String m = r.doRead("variables.txt");
18
19 String[] ss = new String[5];
20 ss = m.split("\n");
21
22 String[] kv= new String[5];
23 for (int i=0; i<ss.length; i++) {
24 kv = ss[i].split("=");
25 String eol = System.getProperty("line.seperator");
26 String test = kv[1];
27 String[] split = new String[5];
28 split = test.split("\n");
29
30
31
32
33 String first = split[0];
34 //String second = split[1];
35 //String third = split[2];
36 //String fourth = split[3];
37 //String fifth = split[4];
38 System.out.println(first);
39 }

When every line looks like
x=1 y=15 z=128 topx=100 leftx=150 label= this is a test
you should first split at a whitespace to get 5 parts (x=1, y=15, ...) and then at = to get the "key" and "value" part of each part.

check this out:
String s = "x=1\ny=15\nz=128\ntopx=100\nleftx=150\nlabel= this is a test";
String[] ss = s.split("\n");
System.err.println( Arrays.asList(ss[0].split("=")) );

Related

Java scanner delimiter causes my integer to not be read properly

So I'm creating a scanner to read off of a simple text file:
import java.io.*;
import java.util.Scanner;
public class Weather {
public static void main(String[] args) throws FileNotFoundException {
int a;
File weatherData = new File("C:\\Users\\taddi\\eclipse-workspace\\COS_160_ASSIGNMENT_10\\src\\PortlandWeather1941to2018.txt");
Scanner scnr = new Scanner(weatherData);
scnr.useDelimiter("//");
int totalCount = scnr.nextInt();// this reads the number at the beginning and uses it so I know how many times to run the loop
String throwAway1 = scnr.nextLine();//these statement are used to throw a way the rest of line 1, and all of line 2 and 3
String throwAway2 = scnr.nextLine();
String throwAway3 = scnr.nextLine();
int[] month = new int[totalCount];
int[] day = new int[totalCount];
int[] year = new int[totalCount];
int[] tmax = new int[totalCount];
int[] tmin = new int[totalCount];
for(a = 0; a < totalCount; a ++) {
month[a] = scnr.nextInt();
System.out.println(month[a]);
day[a] = scnr.nextInt();
System.out.println(day[a]);
year[a] = scnr.nextInt();
tmax[a] = scnr.nextInt();
tmin[a] = scnr.nextInt();
}
}
}
The first part of the text file is an integer I'm trying to read. For some reason, it only reads that integer when I comment out the scnr.useDelimiter("//"); line, otherwise I get an InputMismatchException
I'd love to just get rid of all the unnecessary words and slashes in the text file but that wouldn't satisfy the assignment. What's going wrong with the delimiter? How do I read the integer?
Your delimiter is a string, and it will not work in your use case the way you want.
I assume your sample data is like this (ignoring the header lines) ...
01/01/1941 38 25
01/02/1941 32 20
... so you are looking to get each number - the date elements and the tmax/tmin values - so a single delimiter character of '/' would only break up the date.
For example:
final String data =
"01/01/1941 38 25 \n"+
"01/02/1941 32 20 \n";
Scanner scnr = new Scanner(data);
scnr.useDelimiter("/");
while(scnr.hasNext()) {
System.out.println(scnr.next());
}
scnr.close();
outputs the following ...
01
01
1941 38 25
01
02
1941 32 20
showing that it splits on the date d/m/y slashes, but the year and tmax and tmin are bundled together.
Adjusting the scanner to use a Pattern delimiter allows us to split on the slashes and the spaces.
final String data =
"01/01/1941 38 25 \n"+
"01/02/1941 32 20 \n";
Scanner scnr = new Scanner(data);
scnr.useDelimiter(Pattern.compile("[/ ]+"));
while(scnr.hasNext()) {
System.out.println(scnr.next());
}
scnr.close();
}
giving the output I think you want:
01
01
1941
38
25
01
02
1941
32
20
However, note that in my example data I have trailing whitespace on each line and they are thus also returned as empty String tokens. If I was scanning for nextInt() I would get an java.util.InputMismatchException error. Depending on the exact formatting of your input you may need to cater for that.

Data evaluation from text file

I need some help. I dont know how to solve my problem.
I have text file in this format:
personx 25
personz 2
persony 5
persony 7
personi 55
personx 25
I need to count the numbers for every person. The output should be "personx = 50" etc.
I can not use my old system where I knew there is 10 people. So I had 10 variables and I just went through the file with scanner and checked if line starts with "personx" then count the number to variable personx etc. I dont want to use these variables now. I dont want to change code after every new person.
How to solve this? I want to have this output sorted from highest to lowest:
personi = 55
personx = 50
persony = 12
personz = 2
Is that possible without using variables personi, personx, persony, personz ? My idea was to go through the file and scan the names. Save the name into an array and add another name into an array if that name is not in the array yet. So I will have the names.
Next I will scan the file again and check for the name and number. Check name + number and then save the number into another array on the same possition as the name in the first array. So I will have
Names[0] = "personi";
Count[0] = 55;
Names[1] = "personx";
Count[1] = 50;
And then I will just print these two arrays with for cycle.
I dont think that it is the best solution. How would you do it? Is there something better/faster/easier ? And how to solve that Sorting?
Thank you for your time.
You can us Map<String,Integer>
In this case i used TreeMap which will sort everything for you. If you dont need sorting then just use HashMap instead of TreeMap.
Map<String, Integer> map = new TreeMap();
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("C:/iPhone/persons.txt")));
String line = "";
String [] person = new String[2];
while ((line = reader.readLine()) != null) {
person = line.split(" ");
String name = person[0];
int number = Integer.parseInt(person[1]);
map.put(name,map.getOrDefault(name,0)+number);
}
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
map.forEach((k,v)->System.out.println(k + " = " + v));
}
persons.txt:
personx 25
personz 2
persony 5
persony 7
personi 55
personx 25
Output:
personi = 55
personx = 50
persony = 12
personz = 2
1) Can I use this on file where line is not in my format but it has for example.. this format ? "personx bla bla 25" ? Is it possible to convert it too? how?
Yes you can create method which will do it for you. You can use either string splits or some regex.
2) Why is there String [] person = new String[2]; ?
Mistake, it should be String[1]. Corrected now
3) what is String line = ""; ?
It is just new String where i'm storing every line that i read from file. As you can see, im assigning reder.readLine() in while loop. After that im just splitting it.
EDIT:
Changed code so person can have multiple params but will take only first as name and last as number.
public static void main(String[] args) {
Map<String, Integer> map = new TreeMap();
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("C:/iPhone/persons.txt")));
String line = "";
String [] person;
while ((line = reader.readLine()) != null) {
person = line.split(" ");
String name = person[0];
int number = Integer.parseInt(person[person.length-1]);
map.put(name,map.getOrDefault(name,0)+number);
}
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
map.forEach((k,v)->System.out.println(k + " = " + v));
}
persons.txt:
personx asdasdas dasd asd a 25
personz 2
persony asd asd asd a 5
persony 7
personi 55
personx 25
output:
personi = 55
personx = 50
persony = 12
personz = 2

"java.lang.ArrayIndexOutOfBoundsException: 1" Error When Run

The program compiles fine, but when I run it, I get an error, more specifically this:
java.lang.ArrayIndexOutOfBoundsException: 1
It is getting the error on:
String name = array[1];
I am not sure why.
This is the code with the problem:
infile = new Scanner(new FileReader("EmployeeData.TXT"));
while(infile.hasNext()){
String line = infile.nextLine();
String array[] = line.split(":");
String name = array[1];
String id = array[2];
double salary = Double.parseDouble(array[3]);
Employee e;
if (array[0].equals("s")){
e = new SalariedWorker(id, name, salary);}
else {
boolean overtime = Boolean.parseBoolean(array[4]);
if(overtime){
int maxhu = Integer.parseInt(array[5]);
e = new HourlyWorker(id, name, salary, maxhu);
}
else{
e = new HourlyWorker(id, name , salary);
}
}
company.add(e);
}
For reference, this is the rest of the program:
It reads this text file called "EmployeeData.TXT":
S Washington,George 000001 125000
H MacDonald,Ronald 386218 7.80 true 40
H Walton,Samuel 268517 8.21 false
H Thomas,David 131313 9.45 true 38
H Sanders,HarlandDavid 277651 8.72 false
S Baron,James 368535 310236
You're splitting on ":", and your text file:
S Washington,George 000001 125000
H MacDonald,Ronald 386218 7.80 true 40
H Walton,Samuel 268517 8.21 false
H Thomas,David 131313 9.45 true 38
H Sanders,HarlandDavid 277651 8.72 false
S Baron,James 368535 310236
does not have any such character. So each array will have size 1.
It makes no sense to split on a non-existing character, which makes me very curious why you would choose to use ":". Myself, I'd split on white space, "\\s+"
As an aside, this problem is very amenable to debugging either with a debugger or with some printlns:
while(infile.hasNext()){
String line = infile.nextLine();
System.out.println("Unsplit String: " + line);
String array[] = line.split(":");
System.out.println("Split String: " + java.util.Arrays.toString(array));
Either way, in the future when you have similar problems, find out just what your variables are holding at the time and place of the error, and that often will lead you to the origin of the problem and thereby to its solution.
It is breaking on these lines:
String line = infile.nextLine();
String array[] = line.split(":");
String name = array[1];
String id = array[2];
You are trying to assign the value of array[1] to name... But the array doesn't contain enough elements.
So say you have line = "hey" and you call split on line, your array will only be of length 1, since there is no ":" character to split on.

Extract integers from string

In my app, I get a string. For example:
"1 \n2 4 \n18 \n 3 20 12 \n 4\n23"
I want to get all the integers from the string like
1,2,4,18,3,20,12,4,23.
I can't use string.split. There are only 2 characters except numbers (new line character and space in my string).
Thanks in advance :)
Assuming that you only have integers (in range -2147483648 and 2147483647) in your text (and whitespaces) you can easily use Scanner
String input = "1 \n2 4 \n18 \n 3 20 12 \n 4\n23";
Scanner sc = new Scanner(input);
while(sc.hasNextInt())
System.out.println(sc.nextInt());
For numbers out of these range you can use nextLong or nextBigInteger. But if you are not interested in returning actual type and you are fine with having them as String you can simply use next.
You can use REGEX with \\d+.
public static void main(String[] args) {
String s = "1 \n2 4 \n18 \n 3 20 12 \n 4\n23";
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
}
O/P :
1
2
4
18
3
20
12
4
23
Apart from the Pattern / Matcher reply above...
If only you want to use split, this will work:
String str = "1 \n2 4 \n18 \n 3 20 12 \n 4\n23";
StringBuffer bfr = new StringBuffer();
for (String splitStr: str.split("[\\n\\s]+")){
bfr.append("," + splitStr);
}
System.out.println(bfr.toString().substring(1));
}
or use tokenizer:
String str = "1 \n2 4 \n18 \n 3 20 12 \n 4\n23";
StringTokenizer strToken = new StringTokenizer(str, "[\n ]+");
StringBuffer bfr = new StringBuffer();
while (strToken.hasMoreElements()){
bfr.append("," + strToken.nextElement().toString());
}
System.out.println(bfr.toString().substring(1));
}
You can use StringTokenizer to do it on Android.
StringTokenizer tokens = new StringTokenizer(yourString, "\\n");

cutting column from file in java

I've searched and can't find my question.
I've saved file with linux output ls -l which content is:
drwxr-xr-x 2 usr usr 4096 Jan 20 17:49 file1
drwxrwxr-x 4 usr usr 4096 Jan 20 18:00 file2
drwx------ 2 usr usr 4096 Feb 3 08:48 catalog1
And I want to leave for example only eighth column with hour, and cut off rest of it. What should I do? I'm very beginner with java and programming.
You can use a regular expression to match the timestamp (since it's guaranteed that a time-like value will not appear in any of the other fields). Something like:
// Populate this with the output of the ls -l command
String input;
// Create a regular expression pattern to match.
Pattern pattern = Pattern.compile("\\d{2}:\\d{2}");
// Create a matcher for this pattern on the input string.
Matcher matcher = pattern.matcher(input);
// Try to find instances of the given regular expression in the input string.
while (matcher.find()){
System.out.println(matcher.group());
}
To retrieve any arbitrary column, you can opt to write a regular expression for whichever column you're trying to retrieve, or you may wish to just split each row on the space character, then select by index. For example, to get all of the filesizes:
String input;
String[] inputLines = input.split("\n");
for (String inputLine : inputLines) {
String[] columns = inputLine.split(" ");
System.out.println(columns[4]); // Where 4 indicates the filesize column
}
You need to use StringTokenizer to extract out the exact information that you are looking for. Try the following code:
String value = "drwxr-xr-x 2 usr usr 4096 Jan 20 17:49 file1\n"+
"drwxrwxr-x 4 usr usr 4096 Jan 20 18:00 file2\n"+
"drwx------ 2 usr usr 4096 Feb 3 08:48 catalog1";
StringBuffer sBuffer = new StringBuffer(10);
StringTokenizer sTokenizer = new StringTokenizer(value,"\n");
while (sTokenizer.hasMoreTokens())
{
String sValue = sTokenizer.nextToken();
StringTokenizer sToken = new StringTokenizer(sValue," ");
int counter = 0;
while (sToken.hasMoreTokens())
{
String token = sToken.nextToken();
counter++;
if (counter == 8)//8 is the column that you want to leave.
{
sBuffer.append(token+"\n");
break;
}
}
}
System.out.println(sBuffer.toString());

Categories