system.in.read miss execution - java

Why after the first loop, the switch will execute twice before it stop to wait for my input? Is there any char left in the standard input? How can I fix the issue?
while(true)
{
int choice = System.in.read();
switch(choice)
{
case '1':
break;
default:
break;
}
}

InputStream#read only reads a single byte and will not consume the newline character (will be 2 characters, LF and CR on Windows platforms), passing it through to the next read. This read will now not block having received input and the flow will fall through to your default case.
You could use a BufferedReader instead and read a full line:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
...
int choice = Integer.parseInt(br.readLine());

By taking the time to read the documentation you would have noticed that this method takes in a single byte of data. If you hit Enter after you type in the data, then that will add another byte to the System.in stream, meaning the Switch statement has more data to work with.. You should use a Scanner to read streams like this.
Example
Scanner s = new Scanner(System.in);
// Create a scanner object that reads the System.in stream.
int choice = s.nextInt();
// Accept the next int from the scanner.
switch(choice)
{
// Insert selection logic here.
}

If you again print choice somewhere, probably you will get 10 and 13.
'10' is LF (line feed control char).
'13' is CR (carriage return control char).
This is why the switch is executing twice.
And the better way of taking input already have been shown by Reimeus, Chris Cooney.

You can use Break to Labeled Statement in this case. for more information http://www.javaspecialists.eu/archive/Issue110.html
Here is workign code:
import java.io.IOException;
public class Switch {
public static void main(String[] args) throws IOException {
exitWhile: {
while (true) {
System.out.println("type>");
int choice = System.in.read();
switch (choice) {
case '1':
break;
default:
System.out.println("Default");
break exitWhile;
}
}
}
}
}

This is an Infinite Loop. It will just keep taking the input.
You should be using a Scanner to get your input, than System.in.read(), like this:-
Scanner s = new Scanner(System.in);
while(true)
{
int choice = s.nextInt();
if(choice == 1){
break;
}
}
s.close();

Related

How do I process the last line when using `while(scanner.hasNextLine())`?

As the title states, right now I have something that looks like this:
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextLine()){
string input = scanner.nextLine();
switch(input){
case 1:
do stuff;
break;
case 2:
do stuff;
break;
case 3;
printf("we're done here");
scanner.close();
System.exit(1);
}
}
Obviously, my actual code isn't this simple, but the general idea is the same.
The loops work, and it'll process every line until the last.
And here's the problem, it won't process the last line, the one that actually exits the program....
The answer is probably very simple, but I can't really think of it from the top of my head. How can I process the last line?
Try the below code it works, Use System.exit(0) should come outside switch.
Scanner scanner = new Scanner(System.in);
boolean flag = false;
while(scanner.hasNextLine()){
string input = scanner.nextLine();
switch(input){
case 1:
do stuff;
break;
case 2:
do stuff;
break;
case 3;
printf("we're done here");
flag = true;
break;
}
if(flag) {
System.exit(0); //try 'break' too.
}
}
You need to move the code for the last case statement to the outside of the while loop. The scanner won't have another line and the loop will break.

Java: Read input without knowing number of input lines

This might be very very basic or may be something I am totally missing. I have started doing some competitive programming on online channels. I have to read comma separated strings and do some manipulations around it but the problem is that I do not know the number of lines of input. Below is the input example
Input 1
John,Jacob
Lesley,Lewis
Remo,Tina
Brute,Force
Input 2
Hello,World
Java,Coder
........
........
//more input lines
Alex,Raley
Michael,Ryan
I am trying to read input and breaking when end of the line is encountered but with no luck. This is what I have been trying
//1st method
Scanner in = new Scanner(System.in);
do{
String relation = in.nextLine();
//do some manipulation
System.out.println(relation);
}while(in.nextLine().equals("")); //reads only first line and breaks
//2nd method
Scanner in = new Scanner(System.in);
while(in.hasNext()){
String relation = in.next();
System.out.println(relation);
if(relation.equals("")){
break;
}
}
//3rd method
Scanner in = new Scanner(System.in);
while(true){ //infinite loop
String relation = in.nextLine();
System.out.println(relation);
if(relation.equals("")){
break;
}
}
Can somebody help here.
PS: Please don't judge. I am new to competitive programming though I know how to take user input in java and difference between next() and nextLine().
Im not gonna write why you shouldn't use Scanner. There are numerous articles why you shouldn't use Scanner in competitive programming. Instead use BufferedReader.
In competitive programming they redirect the input to your code from file.
It works like ./a.out > output.txt < input.txt for example.
So read until null is detected in the while loop.
public static void main(String args[] ) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s;
while((s = br.readLine()) != null)
{
//System.out.println(s);
}
}
For testing through your keyboard, to simulate a null from your keyboard:
Press Ctrl+D. It will break out of the while loop above.
It should be fairly easy. Try
while(in.hasNextLine()){
String relation = in.nextLine();
if("exit".equalsIgnoreCase(relation))break;
//do some manipulation
System.out.println(relation);
}
The method Scanner#hasNextLine simply checks if there is a next line in the input, doesn't really advance the scanner. On the other hand, Scanner#nextLine reads the input as well as advances the scanner.
Update you might want to put some condition to exit the loop. E.g. the above snippet stops reading more input after it encounters a string "exit".
All your methods can be improved.
But let's consider your second method of while loop.
Scanner in = new Scanner(System.in);
String s;
while(in.hasNext()){
s=in.nextLine();
System.out.println(s);
}
In the same way, you can change each of your codes.
Also you can use BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); to buffer your input then check for in.readLine()) != null
Other than the above two methods (Buffered Reader method & Scanner method), I have another method for solving this issue. Have a look at the following code, you can catch NoSuchElementException to solve this issue , though I didn't recommended this as Exception handling is a costly process .
Out of all the methods, the Buffered should only be used during Competitive Coding as it has the least Complexity.
import java.util.*;
public class Program
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
try
{
while(true)
String a=sc.next();
System.out.print(a);
}
catch(NoSuchElementException k)
{
}
}
}

Magic 8-ball program

I have an assignment for my Java class to program a Magic 8-ball. It is supposed to generate a random number for the response, contain a "while(true)" statement, and a switch statement for the replies. This is what I have so far. I can't seem to figure out how to work the "while(true)" statement in without it repeating infinitely.
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String question;
int retry;
int q1;
System.out.print("What is your question for the Magic 8-bit 8-ball? ");
question = input.next();
System.out.print(process());
/*This is where I am having the problem. How do I work a "while(true)" in
* to where this won't infinitely repeat?
*/
}
public static int process() {
Random rand1 = new Random();
int random = rand1.nextInt(9);
int ans = random;
switch (ans) {
default: System.out.println("Does not compute!! Error! Error!");break;
case 1: System.out.println("The answer is.............. 42");break;
case 2: System.out.println("To get to the other side!!!");break;
case 3: System.out.println("Out of memory! Try again!");break;
case 4: System.out.println("Who do you think I am, IBM's Watson?");break;
case 5: System.out.println("Danger Will Robinson!! Danger!!");break;
case 6: System.out.println("What do you think?");break;
case 7: System.out.println("Fatal error.....nahhh just kidding");break;
case 8: System.out.println("Well, this is fun....NOT!");break;
case 9: System.out.println("Um...... 1,000,000,000,000,000,000,000?");break;
}
return ans;
}
}
Hum, the point of a while (true) loop is to be infinite, unless you add a break statement in it.
while (true) {
doStuff();
// if someCondition is true, this will exit the loop
if (someCondition)
break;
}
Note that this is equivalent to
do {
doStuff();
} while (!someCondition);
or
boolean someCondition = false;
while (!someCondition) {
doStuff();
}
It is usually preferrable to not have an infinite loop (while (true) for example) and have an explicit condition instead. Some exceptions exist, for example if the condition is complicated to express or if you want to break the loop at a particular position of the loop and not at the beginning or at the end :
while (true) {
doStuff();
if (someCondition)
break;
doSomeOtherStuff();
}
One of the many possible ways:
Create a a char and assign it to 'Y' (i.e. char continueLoop = 'Y').
Use this to control the while statement (i.e. while(char == 'Y') ).
Ask the user for input and process the input (i.e. System.out.println("Continue? Y/N") and then use Scanner to read the input and assign it to continueLoop.
You can create something similar using booleans.

Program goes in an infinite loop

This program goes in an infinite loop in while cycle. Please, can someone tell me why?
import java.util.Scanner;
public class program {
public static void main(String[] pars) {
System.out.println("Insert something.");
Scanner read = new Scanner(System.in);
String s = "";
while(read.hasNext()) {
System.out.println(read.next());
}
System.out.println("End of program");
}
}
Read the Javadoc of Scanner#hasNext():
Returns true if this scanner has another token in its input. This method may block while waiting for input to scan. The scanner does not advance past any input.
Hence the while loop will always be executed in your case, each time waiting for input from the user. Since the Scanner is linked to System.in, the input stream will always block until the user inputs a string and hasNext() will always return true, unless the user signals the end of file (e.g. through the Ctrl+z combination on Windows). Scanner#hasNext() is more convenient when reading from files where the input size is known and the end of the file marks the end of the stream.
One way to end the loop here is to add a condition on the input:
while (read.hasNext()) {
s = read.next();
if(s.equals("quit")) {
break;
}
System.out.println(s);
}
P.S.: It is more conventional to name classes starting with an uppercase letter.
The problem is this line:
while(read.hasNext()) {
If you use System.in as a stream provided by the user, it will - if no such input is available - as #manouti says, block and wait for input. But even if you provide input, it will keep waiting. The system has no means to detect whether the user wants to provide additional input in the future.
It will only stop, if the Stream ends. This can be under two conditions:
The end of the file (in case of I/O redirection like java -jar program.jar < input.dat; or
The user marks the end of a stream, in most shells with Ctrl+D. This marks the end-of-stream.
An alternative is to provide some kind of stop directive. Something like "END". Thus:
while(read.hasNext()) {
String nx = read.next();
if(nx.equals("END")) {
break;
}
System.out.println(nx);
}
Just remove while loop
public static void main(String[] pars) {
System.out.println("Insert something.");
Scanner read = new Scanner(System.in);
String s = "";
System.out.println(read.next());
System.out.println("End of program");
}
Or if u want display certain no.of string then mention condition properly.
public static void main(String[] pars) {
System.out.println("Insert something.");
Scanner read = new Scanner(System.in);
String s = "";
int i=0;
while(i<5) {
System.out.println(read.next());
i++;
}
System.out.println("End of program");
}

Problem with Java Scanner sc.nextLine();

sry about my english :)
Im new to Java programming and i have a problem with Scanner. I need to read an Int, show some stuff and then read a string so i use sc.nextInt(); show my stuff showMenu(); and then try to read a string palabra=sc.nextLine();
Some one told me i need to use a sc.nextLine(); after sc.nextInt(); but i dont understand why do you have to do it :(
Here is my code:
public static void main(String[] args) {
// TODO code application logic here
Scanner sc = new Scanner(System.in);
int respuesta = 1;
showMenu();
respuesta = sc.nextInt();
sc.nextLine(); //Why is this line necessary for second scan to work?
switch (respuesta){
case 1:
System.out.println("=== Palindromo ===");
String palabra = sc.nextLine();
if (esPalindromo(palabra) == true)
System.out.println("Es Palindromo");
else
System.out.println("No es Palindromo");
break;
}
}
Ty so much for your time and Help :D
nextInt() only reads in until it's found the int and then stops.
You have to do nextLine() because the input stream still has a newline character and possibly other non-int data on the line. Calling nextLine() reads in whatever data is left, including the enter the user pressed between entering an int and entering a String.
When you input a value (whether String, int, double, etc...) and hit 'enter,' a new-line character (aka '\n') will be appended to the end of your input. So, if you're entering an int, sc.nextInt() will only read the integer entered and leave the '\n' behind in the buffer. So, the way to fix this is to add a sc.nextLine() that will read the leftover and throw it away. This is why you need to have that one line of code in your program.

Categories

Resources