Java methood split() not working with comma, array out of bounds - java

I am trying to separate a string of an address entered by a user that is divided by commas. For example, If the user input the address
"4367, 56th Avenue, Vancouver, BC, V4K1C3"
I want and array with the values
array ["4376", "56th Avenue", "Vancouver", "BC", "V4K1C3"]
With indices 0 through 4. However, when implementing this in one of my classes, I keep getting an Array out of bounds errors when I assign the value of array[1] to a variable - As if everything is going into the 0 index of the array. Here is a snippet I wrote up that illustrates the issue:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String fullAddress = input.next();
String[] arr = fullAddress.split(",");
System.out.println(arr[0]);
System.out.println(arr[1]); //error java.lang.ArrayIndexOutOfBoundsException: 1
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
}
}
What is going wrong here?

Problem is you are using next() which uses <space> as delimiter. With given input as:
4367, 56th Avenue, Vancouver, BC, V4K1C3
Using next(), you end up fullAddress = "4367,". On split you get arr = ["4367"], hence you get exception at arr[1].
Use nextLine() instead.
String fullAddress = input.nextLine();

You need to use nextLine() instead of next(). You also should use the following regex to avoid the spaces:
String[] arr = fullAddress.split(",\\s+");

The issue is with next()
String fullAddress = input.next();
as it just reads just the input, not the end of line or anything after the input.
You need to change it to
String fullAddress = input.nextLine();

String fullAddress = input.nextLine();
String[] arr = fullAddress.split(",");
for(String k : arr)
System.out.println(k); //better approach to avoid out of bound exception

use nextLine() instead of next()
next() will only return what comes before a space.
nextLine() automatically moves the scanner down after returning the
current line.
for your input 4367, 56th Avenue, Vancouver, BC, V4K1C3
your fullAddress contains 4367, so after split() you have only 1 item and your are trying to access 2nd element so you are getting java.lang.ArrayIndexOutOfBoundsException: 1

If you use split with comma, don't forget to use trim() on each token because if you have something like this: "4367, 56th Avenue, Vancouver, BC, V4K1C3" the array will look like this:
array ["4376", " 56th Avenue", " Vancouver", " BC", " V4K1C3"]
There will be leading space without trim()

Related

Using scanner.next() to return the next n number of characters

I'm trying to use a scanner to parse out some text but i keep getting an InputMismatchException. I'm using the scanner.next(Pattern pattern) method and i want to return the next n amount of characters (including whitespace).
For example when trying to parse out
"21 SPAN 1101"
I want to store the first 4 characters ("21 ") in a variable, then the next 6 characters (" ") in another variable, then the next 5 ("SPAN "), and finally the last 4 ("1101")
What I have so far is:
String input = "21 SPAN 1101";
Scanner parser = new Scanner(input);
avl = parser.next(".{4}");
cnt = parser.next(".{6}");
abbr = parser.next(".{5}");
num = parser.next(".{4}");
But this keeps throwing an InputMismatchException even though according to the java 8 documentation for the scanner.next(Pattern pattern) it doesn't throw that type of exception. Even if I explicitly declare the pattern and then pass that pattern into the method i get the same exception being thrown.
Am I approaching this problem with the wrong class/method altogether? As far as i can tell my syntax is correct but i still cant figure out why im getting this exception.
At documentation of next(String pattern) we can find that it (emphasis mine)
Returns the next token if it matches the pattern constructed from the specified string.
But Scanner is using as default delimiter one or more whitespaces so it doesn't consider spaces as part of token. So first token it returns is "21", not "21 " so condition "...if it matches the pattern constructed from the specified string" is not fulfilled for .{4} because of its length.
Simplest solution would be reading entire line with nextLine() and splitting it into separate parts via regex like (.{4})(.{6})(.{5})(.{4}) or series of substring methods.
You might want to consider creating a convenience method to cut your input String into variable number of pieces of variable length, as approach with Scanner.next() seems to fail due to not considering spaces as part of tokens (spaces are used as delimiter by default). That way you can store result pieces of input String in an array and assign specific elements of an array to other variables (I made some additional explanations in comments to proper lines):
public static void main(String[] args) throws IOException {
String input = "21 SPAN 1101";
String[] result = cutIntoPieces(input, 4, 6, 5, 4);
// You can assign elements of result to variables the following way:
String avl = result[0]; // "21 "
String cnt = result[1]; // " "
String abbr = result[2]; // "SPAN "
String num = result[3]; // "1101"
// Here is an example how you can print whole array to console:
System.out.println(Arrays.toString(result));
}
public static String[] cutIntoPieces(String input, int... howLongPiece) {
String[] pieces = new String[howLongPiece.length]; // Here you store pieces of input String
int startingIndex = 0;
for (int i = 0; i < howLongPiece.length; i++) { // for each "length" passed as an argument...
pieces[i] = input.substring(startingIndex, startingIndex + howLongPiece[i]); // store at the i-th index of pieces array a substring starting at startingIndex and ending "howLongPiece indexes later"
startingIndex += howLongPiece[i]; // update value of startingIndex for next iterations
}
return pieces; // return array containing all pieces
}
Output that you get:
[21 , , SPAN , 1101]

Why does System.out.println print a new line while System.out.print prints nothing?

I am having trouble with split function. I do not know how it works.
Here is my source code:
// Using println to print out the result
String str = " Welcome to Java Tutorial ";
str = str.trim();
String[] arr = str.split(" ");
for (String c : arr) {
System.out.println(c);
}
//Using print to print out the result
String str = " Welcome to Java Tutorial ";
str = str.trim();
String[] arr = str.split(" ");
for (String c : arr) {
System.out.print(c);
}
and the results are:
The first is the result when using println, the second is the result when using print,
I do not understand why space appears in println, while it does not appear in print. Can anyone explain it for me?
Since you have many spaces in your string, if you look at the output of split function, the resulted array looks like
[Welcome, , , , , , , to, , , , Java, , , , , Tutorial]
So if you look close they are empty String's "".
When you do a println("") it is printing a line with no string.
However when you do print(""), it is no more visibility of that string and it looks nothing getting printed.
If you want to separate them regardless of spaces between them, split them by white space.
Lastly, trim() won't remove the spaces within the String. It can only trim spaces in the first and last.
What you are doing is splitting by every individual white space. So for every space you have in your string, it is split as a separate string If you want to split just the words, you can use the whitespace regex:
String[] arr = str.split("\\s+");
This will fix your problem with the consecutive whitespaces you are printing.
Also, When you use print instead of println your print value DOES NOT carry over to the next line. Thus when you cann println("") you are just going to a new line.
println() method prints everything in a new line but the print() method prints everything in the same line.
So, when you are splitting your string by space(" ") then,
for the first one, the string is splitting for every space. So, every time a new line comes while printing. You can't see anything just the new line because you are printing: "" this. Because your code is:
System.out.println("");
But for the second one, the string is splitting for every space but you are using print() method that's why it's not going to the new line.
You can overcome this by regex.
You can use this regex: \\s+
So, you have to write:
String[] arr = str.split("\\s+");

Using Scanner hasNext() and hasNextLine() to retrieve 2 elements per line

In Java, if you were given a text file with two elements per line, how can we grab those elements separately?
For example say we have a 5 line text file with the following:
a morgan
b stewart
c david
d alfonso
e brittany
and let's say we want to store the single char in a variable and the name in another variable. How do we do this is java?
I have implemented some code somewhat like this:
while(scanner.hasNextLine()){
for(int i = 0; i < 2; i++){
char character = scanner.hasNextChar(); // doesn't exist but idk how
String name = scanner.hasNext();
}
}
Basically I have a while loop reading each 2 elements line by line and in each line there is a for loop to store each element in a variable. I am just confused on how to extract each separate element in java.
Considering that you're using scanner.hasNextLine() as your loop condition. You can split the String then collect the result as needed.
while (scanner.hasNextLine()){
String[] result = scanner.nextLine().split(" ");
char character = result[0].charAt(0);
String name = result[1];
}
You can split the line with the whitespace character by using the String.split(String regex) method.
It will produce an array of two String.
If you invoke while(scanner.hasNextLine()){ to get an input, you should invoke String name = scanner.nextLine(); to retrieve the input.
The hasNext() method returns a boolean to indicate if this scanner has another token in its input.
Doing while(scanner.hasNextLine()){ and scanner.hasNext() is redundant.

How to use split function when input is new line?

The question is we have to split the string and write how many words we have.
Scanner in = new Scanner(System.in);
String st = in.nextLine();
String[] tokens = st.split("[\\W]+");
When I gave the input as a new line and printed the no. of tokens .I have got the answer as one.But i want it as zero.What should i do? Here the delimiters are all the symbols.
Short answer: To get the tokens in str (determined by whitespace separators), you can do the following:
String str = ... //some string
str = str.trim() + " "; //modify the string for the reasons described below
String[] tokens = str.split("\\s+");
Longer answer:
First of all, the argument to split() is the delimiter - in this case one or more whitespace characters, which is "\\s+".
If you look carefully at the Javadoc of String#split(String, int) (which is what String#split(String) calls), you will see why it behaves like this.
If the expression does not match any part of the input then the resulting array has just one element, namely this string.
This is why "".split("\\s+") would return an array with one empty string [""], so you need to append the space to avoid this. " ".split("\\s+") returns an empty array with 0 elements, as you want.
When there is a positive-width match at the beginning of this string then an empty leading substring is included at the beginning of the resulting array.
This is why " a".split("\\s+") would return ["", "a"], so you need to trim() the string first to remove whitespace from the beginning.
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.
Since String#split(String) calls String#split(String, int) with the limit argument of zero, you can add whitespace to the end of the string without changing the number of words (because trailing empty strings will be discarded).
UPDATE:
If the delimiter is "\\W+", it's slightly different because you can't use trim() for that:
String str = ...
str = str.replaceAll("^\\W+", "") + " ";
String[] tokens = str.split("\\W+");
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String line = null;
while (!(line = in.nextLine()).isEmpty()) {
//logic
}
System.out.print("Empty Line");
}
output
Empty Line

Split method is splitting into single String

I have a little problem:
I have a program that split a String by whitespace (only single ws), but when I assign that value to the String array, it has only one object inside. (I can print only '0' index).
Here is the code:
public void mainLoop() {
Scanner sc = new Scanner(System.in);
String parse = "#start";
while (!parse.equals("#stop") || !parse.isEmpty()) {
parse = sc.next();
String[] line = parse.split("[ ]");
System.out.println(line[0]);
}
}
The 'mainLoop' is called from instance by method 'main'.
By default Scanner#next delimits input using a whitespace. You can use nextLine to read from the Scanner without using this delimiter pattern
parse = sc.nextLine();
The previous points mentioned in the comments are still valid
while (!parse.equals("#stop") && !parse.isEmpty()) {
parse = sc.nextLine();
String[] line = parse.split("\\s");
System.out.println(Arrays.toString(line));
}
When you call next on scanner it returns next token from input. For instance if user will write text
foo bar
first call of next will return "foo" and next call of next will return "bar".
Maybe consider using nextLine instead of next if you want to get string in form "foo bar" (entire line).
Also you don't have to place space in [] so instead of split("[ ]") you can use split(" ") or use character class \s which represents whitespaces split("\\s").
Another problem you seem to have is
while( !condition1 || !condition2 )
If you wanted to say that loop should continue until either of conditions is fulfilled then you should write them in form
while( !(condition1 || condition2) )
or using De Morgan's laws
while( !condition1 && !condition2 )
If you want to split by a single whitespace, why don't you do it?
String[] line = parse.split(" ");

Categories

Resources