Java: Read token by token of an input string - java

I'm using the Scanner class as stdin for read input from keybord.
I would read token by token the string insert until the end of the line.
token are separated by white spaces.
this is my code:
Scanner in = new Scanner(System.in);
int count=0;
while(in.hasNextLine()){
while(in.hasNext()){
String s=in.next();
System.out.println(s);
if(s.equals("\n"))
break;
count++;
}
break;
}
System.out.println(count);
The problem is that when i press enter, it seems considering it like a white space and it never exit from while block, so it continues to expect another input.
the only way to exit from the while and end the program in Linux is to press ctrl+D (=enter) but i'm searching another way...
I tried to insert an if statement which check if the token is a "\n" but it doesn't work.
Can you help me find a solution to the problem?

The in.hasNextLine() and in.hasNext() methods are blocking ones when used with streams: if there is no new line or new token, they will wait until you write something and press enter again.
If you only want one line you can use something like:
package test;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
int count=0;
Scanner in =new Scanner(System.console().readLine()); //scanning just one line
while(in.hasNext()){
String s=in.next();
System.out.println(s);
count++;
}
System.out.println(count);
in.close();
}
}
Note:
If you execute this code from an IDE, there is no console, so System.console() return null. In order to run it from the command line you need to type something like:
$ pwd
/home/user/development/workspace/test/bin
$ ls
test
$ ls test
Test.class
$ java -classpath /home/user/development/workspace/test/bin/ test.Test

Related

Scanner.hasNextLine - always true

I need to read data from standard input.
And I want to print it to standard output.
I use Scanner for this:
import java.util.Scanner;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
int countLines = 1;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
sb.append(countLines).append(" ").append(line);
}
System.out.println("finish");
System.out.println(sb.toString());
scanner.close();
}
I input this data:
Hello world
I am a file
Read me until end-of-file.
But hasNextLine()) is always true. And as result never print "finish"
Your code seems to work fine. Are you sure you output EOF correctly? Try Ctrl+D (Cmd+D on Mac) or Ctrl+Z on Windows, as mentioned here: How to send EOF via Windows terminal
There is no condition in which the loop will be false, it'll read the lines forever and ever. Consider adding a stop keyword like "stop"
while(scanner.hasNextLine())
{
String line = scanner.nextLine();
if(line.equalsIgnoreCase("stop"))
{
break;
}
//whatever else you have in the loop
}
Unless you stop it, it'll always be true. As pointed out by #Aaron
Scanner.hasNextLine() blocks waiting for a new line, it will only return false if you close the stream (using Ctrl-Z or D as Liel mentions in his answer)

Why are print and printf not printing anything until I've input something?

I want to print out a prompt on the same line as I'm asking for input, but when I execute this code in intellij it only prints the prompt after something has been input.
I've tried adding a '%n' to the end of the first printf which worked, but that doesn't do what I want as I want the input to be on the same line.
I've also tried using System.out.flush() after the first printf but that doesn't seem to be doing anything.
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
Scanner input = new Scanner(System.in);
System.out.printf("Input something: ");
System.out.flush();
String str = input.nextLine();
System.out.printf("You input: %s\n", str);
}
}
I expect the printf("Input something: ") to be printed on the same line as I input on, like so (from Notepad++):
But when I run the same code in intellij this is what I get:

BlueJ - My program compiles with no errors but doesn't run

Hello I'm having problems with a program that's supposed to take in a string and then capitalize the first letters of each word using the Character Wrapper class.
import java.util.*;
public class wrapper
{
public static void main(String[] args)
{
Scanner input= new Scanner(System.in);
String s1;
s1=input.nextLine();
s1= s1.trim();
int howLong= s1.length();
int i;
int counter=0;
char cho;
for(counter=1; counter<= howLong+1; counter++)
{
cho=s1.charAt(counter);
if(Character.isLetter (cho) && ! Character.isLetter(s1.charAt(counter-1)))
{
System.out.print( Character.toUpperCase(cho) );
}
else
{
System.out.print(cho);
}
System.out.println();
}
}
}
That's the program so far, but while it compiles with no errors according to BlueJ, it doesn't run. Any help as to why this is happening would be great.
Edit: Changed the program to what I believe would make it not just print out the spaces that the char variable was initialized to, but it still does not run. Maybe there's something wrong with the loop?
The reason your program compiles but doesn't run is because of the line s1=input.nextLine();. At this line, the program is waiting for input from the user to use as the string s1, but does not show the terminal in order for the user to give such input. A way you can get around this is to force the terminal to show itself before that line. I would recommend putting something like
System.out.println("Enter input:");
before the line, so that the terminal will show itself & the user can enter input into it. From there, you can work on the program like you would normally.

Java : How to use scanner.hasNextLine without Ctrl+Z in a console program

Say I have the below code
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
line = scanner.nextLine();
//do something
}
And my input in the console is goes like this.
Wayne Rooney
Luis Nani
Shinji Kagawa
I want to read this line by line.
But the problem is the method hasNextLine blocks waiting for the input after the third line as the input from the keyboard (System.in) never reaches EOF.
Now, how do I reach EOF just by pressing enter key? because I don't want to tell the user to press the Ctrl+z to run my program.
How is it generally done? Any thoughts?
I am looking for a solution from the Java side and not any commands on the console.
Thanks in advance
When you press enter twice, you end up reading an empty line. You can test for this:
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.equals(""))
break; // this will exit the loop
//do something
}
Now, the loop will end if you press enter twice without typing anything between.
How is it generally done?: It is usually done by showing a message to the user and requesting some special word to finish the input.
public static void main(String[] args) throws IOException
{
Scanner scanner = new Scanner(System.in);
String line;
System.out.println("Enter names (\"QUIT\" to finish)");
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.equals("QUIT")) {
break;
}
}
// ...
}
In the example above the special word used is "QUIT", of course you will change this to a more appropriated one.

How to get out of while loop in java with Scanner method "hasNext" as condition?

I ran into an issue. Below is my code, which asks user for input and prints out what the user inputs one word at a time.
The problem is that the program never ends, and from my limited understanding, it seem to get stuck inside the while loop. Could anyone help me a little?
import java.util.Scanner;
public class Test{
public static void main(String args[]){
System.out.print("Enter your sentence: ");
Scanner sc = new Scanner (System.in);
while (sc.hasNext() == true ) {
String s1 = sc.next();
System.out.println(s1);
}
System.out.println("The loop has been ended"); // This somehow never get printed.
}
}
You keep on getting new a new string and continue the loop if it's not empty. Simply insert a control in the loop for an exit string.
while(!s1.equals("exit") && sc.hasNext()) {
// operate
}
If you want to declare the string inside the loop and not to do the operations in the loop body if the string is "exit":
while(sc.hasNext()) {
String s1 = sc.next();
if(s1.equals("exit")) {
break;
}
//operate
}
The Scanner will continue to read until it finds an "end of file" condition.
As you're reading from stdin, that'll either be when you send an EOF character (usually ^d on Unix), or at the end of the file if you use < style redirection.
When you use scanner, as mentioned by Alnitak, you only get 'false' for hasNext() when you have a EOF character, basically... You cannot easily send and EOF character using the keyboard, therefore in situations like this, it's common to have a special character or word which you can send to stop execution, for example:
String s1 = sc.next();
if (s1.equals("exit")) {
break;
}
Break will get you out of the loop.
Your condition is right (though you should drop the == true). What is happening is that the scanner will keep going until it reaches the end of the input. Try Ctrl+D, or pipe the input from a file (java myclass < input.txt).
it doesn't work because you have not programmed a fail-safe into the code. java sees that the scanner can still collect input while there is input to be collected and if possible, while that is true, it keeps doing so. having a scanner test to see if a certain word, like EXIT for example, is fine, but you could also have it loop a certain number of times, like ten or so. but the most efficient approach is to ask the user of your program how many strings they wish to enter, and while the number of strings they enter is less than the number they put in, the program shall execute. an added option could be if they type EXIT, when they see they need less spaces than they put in and don't want to fill the next cells up with nothing but whitespace. and you could have the program ask if they want to enter more input, in case they realize they need to enter more data into the computer.
the program would be quite simplistic to make, as well because there are a plethera of ways you could do it. feel free to ask me for these ways, i'm running out of room though. XD
If you don't want to use an EOF character for this, you can use StringTokenizer :
import java.util.*;
public class Test{
public static void main(){
Scanner sc = new Scanner (System.in);
System.out.print("Enter your sentence: ");
String s=sc.nextLine();
StringTokenizer st=new StringTokenizer(s," ");//" " is the delimiter here.
while (st.hasMoreTokens() ) {
String s1 = st.nextToken();
System.out.println(s1);
}
System.out.println("The loop has been ended");
}
}
I had the same problem and I solved it by reading the full line from the console with one scanner object, and then parsing the resulting string using a second scanner object.
Scanner console = new Scanner(System.in);
System.out.println("Enter input here:");
String inputLine = console.nextLine();
Scanner input = new Scanner(inputLine);
List<String> arg = new ArrayList<>();
while (input.hasNext()) {
arg.add(input.next().toLowerCase());
}
You can simply use one of the system dependent end-of-file indicators ( d for Unix/Linux/Ubuntu, z for windows) to make the while statement false. This should get you out of the loop nicely. :)
Modify the while loop as below. Declare s1 as String s1; one time outside the loop. To end the loop, simply use ctrl+z.
while (sc.hasNext())
{
s1 = sc.next();
System.out.println(s1);
System.out.print("Enter your sentence: ");
}

Categories