Scanner.hasNext(String s) for "\\d\\s\\d" fails - java

I can't figure out why this loop does not execute even once:
String s = "1 2\n3 4";
Scanner scanner = new Scanner(s);
while(scanner.hasNext("\\d\\s\\d")) {
System.out.printf("%d %d\n", scanner.nextInt(), scanner.nextInt());
}
To my understanding, "\d\s\d" means digit followed by whitespace followed by another digit - exactly what the input is like, but the loop never executes even once.
My intention is to use Scanner with stdin where I want to assure that input has a sequence of two-digit pairs separated by whitespace, but the code example above is simplified, as I assume I'm doing something wrong with how I use the regex.
Can anyone offer an explanation? Thanks in advance.

The pattern String provided to hasNext(String) is applied after the tokenization of the Scanner.
Returns true if the next token matches the pattern constructed from
the specified string.
By default, that is whitespace. So \\d\\s\\d is applied to the character 1 in your String s. Obviously, that doesn't match.

Based on your comments, I believe you are better off using String#split here:
String s = "1 2\n3 4";
toks = s.split( "\n" );
for (String tok: toks)
System.out.printf("<%s>%n", tok);
Output:
<1 2>
<3 4>
PS: You can use Scanner also by using regex to match your numbers:
String s = "1 2\n3 4";
Scanner scanner = new Scanner(s);
while(scanner.hasNext("\\d+")) {
System.out.printf("<%d %d>%n", scanner.nextInt(), scanner.nextInt());
Output:
<1 2>
<3 4>

Related

Java input parsing with delimiter | (pipe)

I know pipe is a special character and I need to use:
Scanner input = new Scanner(System.in);
String line = input.next();
String[] columns = line.split("\\|");
to use the pipe as a delimiter. But it doesn't work as desired when I parse from the command line.
e.g.
When I parse from a file, this just works. However, when the input has a white space, whenever I parse the input from command line, it gives me out of bounds error, because it splits the word into two array element.
input
a|5|Hello|3
output:
columns[0] = "a";
columns[1] = "5";
columns[2] = "Hello";
columns[3] = "3";
bug:
input:
a|5|Hello World|3;
output:
columns[0] = "a";
columns[1] = "5";
columns[2] = "Hello";
columns[3] = "World";
columns[4] = "3";
I want columns[3] as "Hello World". How can I fix this?
I think you should get the data from user by using nextLine() instead of only next().
In my case its working fine just click here and check the source code ..
next() can read the input only till the space. It can't read two words separated by space. Also, next() places the cursor in the same line after reading the input. nextLine() reads input including space between the words (that is, it reads till the end of line n).
A Scanner breaks its input into tokens using a delimiter pattern,
which by default matches whitespace. Source
To overcome, you should use nextline() method instead.
String line = input.nextline();

Java (Length of an input)

So I want to get the length of the input in java, but the (String.length()) doesn't produce a satisfying result.
So when I type this code:
String c = "hi hello";
System.out.print(c.length());
I get 8 which is correct
but when I type this code:
Scanner s = new Scanner(System.in);
String c = s.next();
System.out.print(c.length());
For "hi hello" is the input, I get 2 not 8. I tried again with different inputs and I found that string.length() have a problem with spaces in inputs. for example, if the input was "123456 78" the output would be 6 not 9. Can you tell me how to get the full length of the input? Thanks in advance
Replace s.next() to s.nextLine() and you will get the desired result.
next() finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.
nextLine() returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
-> "123456 78"
s.next().length() -> "123456".length() -> 6
s.nextLine().length() -> "123456 78".length() -> 9
Use nextLine() rather than next() as next() can read the input only till the space.
nextLine() reads input including space between the words (that is, it reads till the end of line \n)
Scanner s = new Scanner(System.in);
String c = s.nextLine();
System.out.print(c.length());
The java.util.Scanner.next() method finds and returns the next
complete token from this scanner. A complete token is preceded and
followed by input that matches the delimiter pattern.
The delimiter here is " ".
You get 2 as length because it says the length of "hi" is 2. If you
want the length of complete string use nextLine() it counts upto "\n"

How to split a string with space being the delimiter using Scanner

I am trying to split the input sentence based on space between the words. It is not working as expected.
public static void main(String[] args) {
Scanner scaninput=new Scanner(System.in);
String inputSentence = scaninput.next();
String[] result=inputSentence.split("-");
// for(String iter:result) {
// System.out.println("iter:"+iter);
// }
System.out.println("result.length: "+result.length);
for (int count=0;count<result.length;count++) {
System.out.println("==");
System.out.println(result[count]);
}
}
It gives the output below when I use "-" in split:
fsfdsfsd-second-third
result.length: 3
==
fsfdsfsd
==
second
==
third
When I replace "-" with space " ", it gives the below output.
first second third
result.length: 1
==
first
Any suggestions as to what is the problem here? I have already referred to the stackoverflow post How to split a String by space, but it does not work.
Using split("\\s+") gives this output:
first second third
result.length: 1
==
first
Change
scanner.next()
To
scanner.nextLine()
From the javadoc
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
Calling next() returns the next word.
Calling nextLine() returns the next line.
The next() method of Scanner already splits the string on spaces, that is, it returns the next token, the string until the next string. So, if you add an appropriate println, you will see that inputSentence is equal to the first word, not the entire string.
Replace scanInput.next() with scanInput.nextLine().
The problem is that scaninput.next() will only read until the first whitespace character, so it's only pulling in the word first. So the split afterward accomplishes nothing.
Instead of using Scanner, I suggest using java.io.BufferedReader, which will let you read an entire line at once.
One more alternative is to go with buffered Reader class that works well.
String inputSentence;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
inputSentence=br.readLine();
String[] result=inputSentence.split("\\s+");
rintln("result.length: "+result.length);
for(int count=0;count<result.length;count++)
{
System.out.println("==");
System.out.println(result[count]);
}
}

Deliminter is not working for scanner

The user will enter a=(number here). I then want it to cut off the a= and retain the number. It works when I use s.next() but of course it makes me enter it two times which I don't want. With s.nextLine() I enter it once and the delimiter does not work. Why is this?
Scanner s = new Scanner(System.in);
s.useDelimiter("a=");
String n = s.nextLine();
System.out.println(n);
Because nextLine() doesn't care about delimiters. The delimiters only affect Scanner when you tell it to return tokens. nextLine() just returns whatever is left on the current line without caring about tokens.
A delimiter is not the way to go here; the purpose of delimiters is to tell the Scanner what can come between tokens, but you're trying to use it for a purpose it wasn't intended for. Instead:
String n = s.nextLine().replaceFirst("^a=","");
This inputs a line, then strips off a= if it appears at the beginning of the string (i.e. it replaces it with the empty string ""). replaceFirst takes a regular expression, and ^ means that it only matches if the a= is at the beginning of the string. This won't check to make sure the user actually entered a=; if you want to check this, your code will need to be a bit more complex, but the key thing here is that you want to use s.nextLine() to return a String, and then do whatever checking and manipulation you need on that String.
Try with StringTokenizer if Scanner#useDelimiter() is not suitable for your case.
Scanner s = new Scanner(System.in);
String n = s.nextLine();
StringTokenizer tokenizer = new StringTokenizer(n, "a=");
while (tokenizer.hasMoreTokens()) {
System.out.println(tokenizer.nextToken());
}
or try with String#split() method
for (String str : n.split("a=")) {
System.out.println(str);
}
input:
a=123a=546a=78a=9
output:
123
546
78
9

Scanner through a line with whitespace and comma

I am new to Java and looking for some help with Java's Scanner class. Below is the problem.
I have a text file with multiple lines and each line having multiple pairs of digit.Such that each pair of digit is represented as ( digit,digit ). For example 3,3 6,4 7,9. All these multiple pairs of digits are seperated from each other by a whitespace. Below is an exampel from the text file.
1 2,3 3,2 4,5
2 1,3 4,2 6,13
3 1,2 4,2 5,5
What i want is that i can retrieve each digit seperately. So that i can create an array of linkedlist out it. Below is what i have acheived so far.
Scanner sc = new Scanner(new File("a.txt"));
Scanner lineSc;
String line;
Integer vertix = 0;
Integer length = 0;
sc.useDelimiter("\\n"); // For line feeds
while (sc.hasNextLine()) {
line = sc.nextLine();
lineSc = new Scanner(line);
lineSc.useDelimiter("\\s"); // For Whitespace
// What should i do here. How should i scan through considering the whitespace and comma
}
Thanks
Consider using a regular expression, and data that doesn't conform to your expectation will be easily identified and dealt with.
CharSequence inputStr = "2 1,3 4,2 6,13";
String patternStr = "(\\d)\\s+(\\d),";
// Compile and use regular expression
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(inputStr);
while (matcher.find()) {
// Get all groups for this match
for (int i=0; i<=matcher.groupCount(); i++) {
String groupStr = matcher.group(i);
}
}
Group one and group two will correspond to the first and second digit in each pairing, respectively.
1. use nextLine() method of Scanner to get the each Entire line of text from the File.
2. Then use BreakIterator class with its static method getCharacterInstance(), to get the individual character, it will automatically handle commas, spaces, etc.
3. BreakIterator also give you many flexible methods to separate out the sentences, words etc.
For more details see this:
http://docs.oracle.com/javase/6/docs/api/java/text/BreakIterator.html
Use the StringTokenizer class. http://docs.oracle.com/javase/1.4.2/docs/api/java/util/StringTokenizer.html
//this is in the while loop
//read each line
String line=sc.nextLine();
//create StringTokenizer, parsing with space and comma
StringTokenizer st1 = new StringTokenizer(line," ,");
Then each digit is read as a string when you call nextToken() like this, if you wanted all digits in the line
while(st1.hasMoreTokens())
{
String temp=st1.nextToken();
//now if you want it as an integer
int digit=Integer.parseInt(temp);
//now you have the digit! insert it into the linkedlist or wherever you want
}
Hope this helps!
Use split(regex), more simple :
while (sc.hasNextLine()) {
final String[] line = sc.nextLine().split(" |,");
// What should i do here. How should i scan through considering the whitespace and comma
for(int num : line) {
// Do your job
}
}

Categories