countTokens() always returns 1 with user input - java

Before we begin, I don't believe this is a repeat question. I've read the question entitled StringTokenzer countTokens() returns 1 with any string, but that does not address the fact that a properly delimited string is counted correctly, but a properly delimited input is not.
When using the StringTokenizer class I've found that the countTokens method returns different outcomes depending on the whether the argument in countTokens was a defined String or a user defined String. For example, the following code prints the value 4.
String phrase = "Alpha bRaVo Charlie delta";
StringTokenizer token = new StringTokenizer(phrase);
//There's no need to specify the delimiter in the parameters, but I've tried
//both code examples with " " as the delimiter with identical results
int count = token.countTokens();
System.out.println(count);
But this code will print the value 1 when the user enters:Alpha bRaVo Charlie delta
Scanner in = new Scanner(System.in);
String phrase;
System.out.print("Enter a phrase: ");
phrase = in.next();
StringTokenizer token = new StringTokenizer(phrase);
int count = token.countTokens();
System.out.println(count);

Use in.nextLine() instead of in.next();

Scanner in = new Scanner(System.in);
String phrase;
System.out.print("Enter a phrase: ");
phrase = in.nextLine();
System.out.print(phrase);
StringTokenizer token = new StringTokenizer(phrase);
int count = token.countTokens();
System.out.println(count);
Print phrase and check that in.next() is returning "Alpha".
As suggested above, Use in.nextLine().

You could try using an InputStreamReader, instead of the Scanner:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String phrase = "";
System.out.print("Enter a phrase: ");
try {
phrase = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
StringTokenizer token = new StringTokenizer(phrase);
int count = token.countTokens();
System.out.println(count);
nextLine() of Scanner also got the job done for me, though.
If you want the delimiter to be a space-character specifically, you might want to pass it to the constructor of StringTokenizer. It will use " \t\n\r\f" otherwise (which includes the space-character, but might not work as expected if e.g. the \n-character is also present inside the phrase).

If you check the value of phrase, after invoking in.next(), you will see that's equal to "Alpha". By definition, Scanner's next() reads the next token.
Use in.nextLine() instead.

Related

Issue with Reading two Int values from a file

I have file with the below data
A,8,43
B,7,42,
C,9,34
I am using the below code to read the data
Scanner input = new Scanner(new File("D:\\test.txt"));
input.useDelimiter(",|\n");
while(input.hasNext()) {
String name = input.next();
int age = input.nextInt();
int height = input.nextInt();
When I am executing the program I am getting InputMisMatch exception,
Please suggest what is mistake.
At end of second line you have , and line separator (I am assuming \n) This means you have empty element between these two delimiters.
So in third iteration
String name = input.next();
int age = input.nextInt();
int height = input.nextInt();
input.next(); is consuming "", which means input.nextInt() will try to consume C.
To solve this problem you can set delimiter to be combination of one or more commas and line separators like
input.useDelimiter("(,|\n)+");
To improve your code even farther instead of \n you can use \\R added in Java 8 (or \r|\n in earlier versions) to handle all line separators, because currently you don't consider \r as delimiter so it can be treated as valid token.
So better solution would be using
input.useDelimiter("(,|\\R)+"); //for readability
or even
input.useDelimiter("[,\r\n]+");
The problem lies at the use of the useDelimiter method. This method accepts a regular expression as a parameter. You can't just say ,|\n to mean "comma or new line". There are rules.
What you should pass in is "[,\\n]+". This means "one or more characters in the following set: [comma, new line character]".
With the regex that you are passing currently, ,|\n, it means that the delimiter should be either , or \n, but not both. So when it encounters the second line:
B,7,42,
this is what happens:
next reads "B"
nextInt reads "7"
nextInt reads "42"
next reads an empty string that is between the "," and the new line.
nextInt now tries to read the next token "C", which it can't.
EXCEPTION!
I would do things differently -- use one Scanner to parse each line of the File and use a 2nd Scanner nested within the while loop to extract tokens or data from the lines obtained from the first Scanner. For example:
String filePath = "D:\\test.txt";
File file = new File(filePath);
// use try-with-resources
try (Scanner input = new Scanner(file)) {
while (input.hasNextLine()) {
String line = input.nextLine();
Scanner lineScanner = new Scanner(line);
lineScanner.useDelimiter("\\s*,\\s*"); // get comma and any surrounding whitespace if present
String name = "";
int age = 0;
int height = 0;
if (lineScanner.hasNext()) {
name = lineScanner.next();
} // else ... throw exception?
if (lineScanner.hasNextInt()) {
age = lineScanner.nextInt();
} // else ... throw exception?
if (lineScanner.hasNextInt()) {
height = lineScanner.nextInt();
} // else ... throw exception?
// use name, age, height here
System.out.printf("%s %s %s%n", name, age, height);
lineScanner.close(); // don't waste resources -- return them
}
} catch (IOException e) {
e.printStackTrace();
}

Java String - How to get chars until and after space

I'm load to variable string using:
Scanner scanner = new Scanner(System.in);
x = scanner.nextLine();
String always looks like: "Random Example". I want to grab first word (before space) for one variable and second word (after space) to next one variable. Can someone show me example?
You can get split a String using .split(String s) and put it in a String[]
String editMe;
Scanner user_input = new Scanner( System.in );
editMe = user_input.nextLine();
String[] edit1 = editMe.split(" ");
If you would like to see the values in the System you can use
int i =0;
for(String s:edit1)
{
System.out.println(s);
i++;
}
See more information on the String variable and how to use it here.
Input obtained from scanning the input stream can be split based on the space character.
Scanner scanner = new Scanner(System.in);
String x = scanner.nextLine();
String array[] =x.split(" ");
In this way, the words are stored in array.

Printing a string backwards

I'm trying to print a string in reverse. i.e.
hello world
should come out as:
dlrow olleh
But the outcome only shows the reverse of the first word. i.e.
olleh
Any thoughts?
import java.util.Scanner;
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.println("Input a string:");
String s;
s = input.next();
String original, reverse = "";
original = s;
int length = original.length();
for ( int i = length - 1 ; i >= 0 ; i-- )
reverse = reverse + original.charAt(i);
System.out.println("Reverse of entered string is: "+reverse);
input.close();
}
}
Using input.next() only stores the next word in the variable (only "hello"). Try this:
System.out.println("Input a string:");
String s;
s = input.nextLine();
System.out.println("entered: " + s);
The line
s=input.next()
will only take one word.
So to get the whole line 'hello world', you've to use the nextLine() function.
s = input.nextLine();
Your scanner object returns only the next complete token through the input.next() method. A token is considered complete when there is a whitespace character. Use the nextLine() method of the scanner to get the complete input if you are using multiple words.
new StringBuilder("hello world").reverse().toString();
Maybe much more simpler.
use s.nextline() instead of s.next() as s.next() read only first token string
Scanner sc= new Scanner(System.in);
String s = sc.nextLine();
System.out.println(new StringBuilder(s).reverse().toString());
From Scanner javadoc:
public String 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. This method may block while waiting for input to
scan, even if a previous invocation of hasNext() returned true.
What happens is that the token delimiter may not be what you're expecting (newline, for instance).
If you wish your program to read the entire line input by the user, you might want to use Scanner.nextLine(), which will read the entire line input by the user, or maybe Scanner.next(String delimiter), which will allow you to enter the desired token delimiter.
Change s = input.next() to s = input.nextLine()
I can't really write some source code but maybe try using two different inputs. After that add each string to it's own variable. After that, reverse them both and add them together as an output.

Why cant I read whole line along with double using Scanner(System.in)?

What actually happens here ?
Why can't I store a String with spaces in between as name ?
I tried the delimiter thing, but didn't worked. Is there a way that will produce the desired output ?
I know .next() works but we might need to store a string with space. Just curious ...
Scanner input=new Scanner(System.in);
System.out.print("Enter number of Students:");
double [] scores = new double[input.nextInt()];
String [] names=new String[scores.length];
for(int i=0;i<names.length;i++){
System.out.println("Enter the students name: ");
names[i] = input.nextLine();
System.out.println("Enter the student scores : ");
scores[i]=input.nextDouble();
}
when you call input.nextInt(), it doesn't consume the new line character on that line, so the following call to input.nextLine(); will consume the newline, and return the empty string. nextDouble() will function properly.
one way to fix this is to call input.nextLine(); immediately before the for loop to consume the extra new line character
Edit:
String [] names=new String[scores.length];
input.nextLine(); //literally add the call right here
for(int i=0;i<names.length;i++){
According to the Javadoc:
A simple text scanner which can parse primitive types and strings using regular expressions.
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace. The resulting tokens may then be converted into values of different types using the various next methods.
What if you replace the default delimiter with "\n" like this:
Scanner s = new Scanner(input).useDelimiter("\\\\n");
This is how it works ! Thanks for concern guys! :)
for(int i=0;i<names.length;i++){
if(input.nextLine().equals("")){
System.out.println("Enter students name : ");
names[i] = input.nextLine();
}
System.out.println("Enter the student scores : ");
scores[i]=input.nextDouble();
}

Java - How to read integers separated by a space into an array

I am having trouble with my project because I can't get the beginning correct, which is to read a line of integers separated by a space from the user and place the values into an array.
System.out.println("Enter the elements separated by spaces: ");
String input = sc.next();
StringTokenizer strToken = new StringTokenizer(input);
int count = strToken.countTokens();
//Reads in the numbers to the array
System.out.println("Count: " + count);
int[] arr = new int[count];
for(int x = 0;x < count;x++){
arr[x] = Integer.parseInt((String)strToken.nextElement());
}
This is what I have, and it only seems to read the first element in the array because when count is initialized, it is set to 1 for some reason.
Can anyone help me? Would it be better to do this a different way?
There is only a tiny change necessary to make your code work. The error is in this line:
String input = sc.next();
As pointed out in my comment under the question, it only reads the next token of input. See the documentation.
If you replace it with
String input = sc.nextLine();
it will do what you want it to do, because nextLine() consumes the whole line of input.
String integers = "54 65 74";
List<Integer> list = new ArrayList<Integer>();
for (String s : integers.split("\\s"))
{
list.add(Integer.parseInt(s));
}
list.toArray();
This would be a easier way to do the same -
System.out.println("Enter the elements seperated by spaces: ");
String input = sc.nextLine();
String[] split = input.split("\\s+");
int[] desiredOP = new int[split.length];
int i=0;
for (String string : split) {
desiredOP[i++] = Integer.parseInt(string);
}
There are alternate ways to achieve the same. but when i tried your code, it seems to work properly.
StringTokenizer strToken = new StringTokenizer("a b c");
int count = strToken.countTokens();
System.out.println(count);
It prints count as 3. default demiliter is " "
I dont know how are you getting your input field. May be it is not returning the complete input in string format.
I think you are using java.util.Scanner for reading your input
java doc from scanner.
A Scanner breaks its input into tokens using a delimiter pattern,
which by default matches whitespace. The resulting tokens may then be
converted into values of different types using the various next
methods.
Hence the input is returning just one Integer and leaving the rest unattended
Read this. Scanner#next(), You should use Scanner#nextLine() instead
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
.
.
.
StringTokenizer st = new StringTokenizer(br.readLine());
int K = Integer.parseInt(st.nextToken());
int N= Integer.parseInt(st.nextToken());

Categories