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

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.

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]

How to select a section of a string from 2 specific points when you cannot use IndexOf in Java

I'm writing a program for a school project where I make an array and synonyms from a text file that we've been given by creating an object called Word which stores the word and its synonym and then making a class called WordArray.
WordArray takes the words and their synonyms from the text file and stores them in the array as Word objects.
Then I have a method called Search() where a parameter is used to find either all words that partially match the parameter.
For Example: if the parameter is rep, the method will return the words repressed and represent), or one word which is exactly the same as the parameter. If there are multiple words that match the parameter, the method will include a number (starting at 1) and place that before the word.
Now I need to have some code in my main class which takes the WordArray (a) and performs the Search() method based on a String that the user inputs.
I then show the user which words have been found based on their input.
If there is only one word returned, it stores that as the word String, If there are more; I ask the user to input a number that corresponds to the number that is included before the word in the list of Strings.
My problem is, I want to store that word in the word String, and the last line of code shows what I have done so far. But I would like it in this format:
word = list.substring(list.indexOf(j), *the character after the end of the word*);
The issue is I'm not sure how to do that, as I can't use LastIndexOf or IndexOf, because the word might be in the middle of a list of multiple words, in which case that wouldn't work.
Are there any String methods I could use?
My code so far is below:
String temp = JOptionPane.showInputDialog("Input a word or part of one:");
String list = a.Search(temp);
String word = "";
System.out.println(list);
if (list.charAt(0) != '1')
{
word = list;
}
else
{
String j = JOptionPane.showInputDialog("Type the number of the word you'd like:");
word = list.substring(list.indexOf(j));
}
No validation here and assuming list contains something:
String temp = JOptionPane.showInputDialog("Input a word or part of one:"); //pp
String list = a.Search(temp);
System.out.println(list); //"1Apple 2Application"
String input = "";
if(list.contains(" ")) //more than one word ???
{
input = JOptionPane.showInputDialog("Type the number of the word you'd like:");
}
String number = input;
String result = Arrays.asList(list.split(" ")).stream()
.filter(e -> e.startsWith(number))
.findFirst()
.get();
System.out.println(result); //1Apple || 2Application

Removing letters from a string using a while loop in Java

while (sentence.indexOf(lookFor) > lookFor)
{
sentence += sentence.substring(sentence.indexOf(lookFor));
}
String cleaned = sentence;
return cleaned;
This is what I have tried to do in order to remove letters. lookFor is a char that was put in already, and sentence is the original sentence string that was put in already. Currently, my code outputs the sentence without doing anything to it.
EX Correct Output: inputting "abababa" sentence; char as "a" --->outputting "bbb"
inputting "xyxyxy" sentence; char "a" ---> outputting "xyxyxy"
You don't need while for a single string. Only if you read a text line after line.
In your case something like
String a = "abababa";
a = a.replace("a","");
would give you the output "bbb"
it probably isn't entering the loop at all.
sentence.indexOf(lookFor) is going to return the place of the character in the string.
lookFor is a char value. A value of 'a' has a numeric value of 97 so the while will only find things after the first 97 characters.
If your code ever entered the loop it would never return.
the substring command you are calling will take the found item to the end of the string.
+=, if it did what you think will append it to itself. so it will take 'ababab' and make it 'abababababab', forever. but luckily you can't use += on a string in java.
What you want is:
String something = "abababab";
something = something.replaceAll("a", "");
If you just need to get rid of letters use the replace method that others have written, but if you want to use a while loop, based on what I've seen of your logic, this is how you'd do it.
while (sentence.indexOf(lookFor) == 0)
sentence = sentence.substring(1);
while (sentence.indexOf(lookFor) > 0)
{
sentence = sentence.substring(0, sentence.indexOf(lookFor)-1)+
sentence.substring(sentence.indexOf(lookFor)+1);
}
return sentence;

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

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

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