Why is scanner reading no input and exiting function? [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I've created a method that asks a user for their favorite number. When I call this function more than once in my main, all method calls thereafter will jump to closing and declare Your favorite number is: 0 without asking for input. I'd like to know why a fresh scanner is reading and accepting no input.
public static void favNumber(){
Scanner scanner = new Scanner(System.in);
System.out.println("Enter you favorite number: ");
int favNumber = 0;
boolean hasNextInt = scanner.hasNextInt();
if(hasNextInt){
favNumber = scanner.nextInt();
scanner.nextLine(); //reads enter character
}
System.out.println("Your favorite number is: " + favNumber);
scanner.close();
}

Your Scanner instance wraps System.in (stdin). When you call scanner.close() at the end of your method, you're actually closing System.in in addition to your scanner. Once the input stream is closed, it can't be opened again.
The solution is, of course, to share a single instance of the Scanner. I note that you're using static methods, so I will similarly use a static instance in the following example. Note how I create the scanner, then I call favNumber(), and I only close the scanner after I finish calling favNumber(). This allows me to call favNumber() multiple times and share the same scanner instance.
private static Scanner scanner; // note that this is a class-level static variable.
public static void main(String[] args) throws Exception {
try {
scanner = new Scanner(System.in); // create the scanner
favNumber(); // call the method
} finally {
scanner.close(); // only close the scanner when we're completely done
}
}
public static void favNumber(){
System.out.println("Enter you favorite number: ");
int favNumber = 0;
boolean hasNextInt = scanner.hasNextInt();
if(hasNextInt){
favNumber = scanner.nextInt();
scanner.nextLine(); //reads enter character
}
System.out.println("Your favorite number is: " + favNumber);
}
An alternative solution would be to pass the scanner instance as a method parameter like this:
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in); // create the scanner
favNumber(scanner); // call the method, pass the scanner
scanner.close(); // only close the scanner when we're completely done
}
public static void favNumber(Scanner scanner){
System.out.println("Enter you favorite number: ");
int favNumber = 0;
boolean hasNextInt = scanner.hasNextInt();
if(hasNextInt){
favNumber = scanner.nextInt();
scanner.nextLine(); //reads enter character
}
System.out.println("Your favorite number is: " + favNumber);
}
You can read more about closing scanners wrapping System.in in this Q&A here: Close a Scanner linked to System.in

Related

Import these scanners into another class?

Again I am very new to Java, and I have this code here:
package Final;
import java.util.Scanner;
public class Position {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner MyPos = new Scanner(System.in);
System.out.println(" Enter Position: ");
String Pos = MyPos.nextLine();
System.out.println("Position: "+Pos);
Scanner MyMains = new Scanner(System.in);
System.out.println("Enter Mains: ");
String Mains1 = MyMains.nextLine();
System.out.println("Mains: "+Mains1);
Scanner WScore = new Scanner(System.in);
System.out.println("Enter Ward Score: ");
String score = WScore.nextLine();
System.out.println(" Average Ward Score is:"+score);
}
}
I was curious if there was a way to possibly import all 3 of my scanners to another class without moving all the actual code from this class? The class I'm trying to move it to is a class called "Player.java". There aren't any problems with my code, but additional input is always appreciate to help me understand and improve my code!
You don't need a new scanner for each variable. What you do need to do is close() a scanner when you are done using it.
You are thinking of the Scanner itself being associated with a variable - when in fact it is associated with System.in...
So, every time you want another variable, just do:
Scanner sc = new Scanner(System.in);
String firstThing = sc.nextLine();
String secondThing = sc.nextLine();
sc.close(); // Do this when you're done storing input from System.in!
Once you have declared your scanner. I'm not sure why you would want to pass the scanner to another class. What you can do easily is pass the variables that you grab from your scanner into a player object.
Just do Player p1 = new Player(stringYouScanned); assuming that you have your constructor in your Player class accept a String.
Or, look up getter and setter methods. Then you can do something like: `p1.setPosition(4);' (you could replace 4 with an int you scanned in, you get the idea).
If for some reason you want to scan input from within the Player, I'd just initialize a new Scanner, but make sure you are doing sc.close(); after you are done processing your input.

How do I make java wait for input before assigning the input to a variable to avoid java.util.NoSuchElementException

I'm studying Java classes and I'm trying to create a code where the user inputs how many objects (in this case "cube") they want to create.
In my main class I have this code written
System.out.println("Enter the amount of objects you want to create");
Scanner objNumInput = new Scanner(System.in);
int objNum = objNumInput.nextInt();
objNumInput.close();
Cube cubes[] = new Cube[objNum];
for (int i = 0; i < objNum; i++){
String cubeName = Cube.inputName();
double cubeLength = Cube.inputLength();
cubes[i] = new Cube(cubeName, cubeLength);
}
in my Cube class I have here:
public static String inputName(){
String cubeName;
Scanner input = new Scanner(System.in);
System.out.println("Enter the name: ");
cubeName = input.nextLine();
return cubeName;
}
public static double inputLength(){
double cubeLength;
Scanner input = new Scanner(System.in);
System.out.println("Enter the length: ");
cubeLength = input.nextDouble();
return cubeLength;
}
When I run it, I can input the number of "cubes" I want to create. Then, it keeps throwing an exception
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at Cube.inputName(Cube.java:40)
at Main.main(Main.java:88)
what's wrong?
Do not close your Scanner, it will close System.in as well.
When a Scanner is closed, it will close its input source if the source implements the Closeable interface
As I understand (correct me if I'm wrong) the reason why you close your objNumInput is that you want to use it in two different methods.
I would suggest you to pass the Scanner as input parameter into your methods inputName and inputLength. Then you'll be able to reuse the same scanner without closing it in between.
public static String inputName(Scanner scanner){
String cubeName;
System.out.println("Enter the name: ");
cubeName = scanner.nextLine();
return cubeName;
}
public static double inputLength(Scanner scanner){
double cubeLength;
System.out.println("Enter the length: ");
cubeLength = scanner.nextDouble();
return cubeLength;
}
...
System.out.println("Enter the amount of objects you want to create");
Scanner objNumInput = new Scanner(System.in);
int objNum = objNumInput.nextInt();
//objNumInput.close(); <-- Do not close the scanner
Cube cubes[] = new Cube[objNum];
for (int i = 0; i < objNum; i++){
String cubeName = Cube.inputName(objNumInput);
double cubeLength = Cube.inputLength(objNumInput);
cubes[i] = new Cube(cubeName, cubeLength);
}
put objNumInput.close(); after for loop in your main method.The reason your program flashes by without pausing the second time because System.in is closed when you do objNumInput.close(); in the line number 3 of main method
closing a Scanner object will close the underlying stream.
-your code only works one time because System.in is getting closed. You cannot "open" System.in again. A closed stream cannot be reopened

How can I re-arrange my code to produce the output I want? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Please could you help me re-arrange my already working code to give me this output described in the bullet points underneath:
'Type your text' window appears
The user enters the text, for example 'hey'
The code prints out the text entered by the user (hey), underneath the code prints out the number of characters (3) and finally another scanner window 'Type your text' appears. So the program loops back to 2 and waits for another line to be typed.
This would look like this:
hey
3
another scanner for the text to be typed in
My code already works and calculates everything, i just ran out of ideas how to re-arrange it to make its output exactly what i want:
System.out.println("Type your text...");
Scanner sc = new Scanner(System.in);
System.out.println(sc.nextLine());
System.out.println(sc.nextLine().length());
System.out.println("Length of String: " + lengthOfString("hey"));
sc.close();
}
private static int lengthOfString(String string) {
int length = -1;
while (true) {
try {
string.charAt(++length);
} catch (StringIndexOutOfBoundsException exception) {
break;
}
}
return length;
}
I am a beginner and I have weak understanding of java so please be clear with your answers and all your answers will be much appreciated, thank you!
The main problem is that you are calling nextLine() twice when you only want to be calling it once. Instead of these two lines:
System.out.println(sc.nextLine());
System.out.println(sc.nextLine().length());
Use this:
String input = sc.nextLine();
System.out.println(input);
System.out.println(input.length());
Another problem is that you are closing sc. This will close the underlying stream (System.in), which you don't want to do. Finally, you need to invoke this code in a loop so that the process is repeated. You don't show the context for this code, but I'm assuming that it's in a method that is being called in a loop or is part of the body of a loop. In either case, it would be better to create a Scanner once and use it repeatedly, rather than creating and disposing of a Scanner for each transaction with the user.
while (true)
{
System.out.println("Type your text...");
String str = sc.nextLine();
System.out.println("Length of String: " + str.length());
}
Have removed unncessary complexity from your code,Try this code:
Scanner sc=new Scanner(System.in);
String s;
while(true) //have created infinite loop as you want to continuously take inputs,
{
System.out.println("Enter value:");
s=sc.next();
if(s.equals("quit")) //if enterd value is "quit" than it comes out of loop ,termination condition to come out
{
break;
}
System.out.println(""+s); //to Print string
System.out.println(""+s.length()); //to print Entered string's length
}
Try out this:
import java.util.Scanner;
public class CountingOccurences {
public static void main(String[] args) {
Scanner inp= new Scanner(System.in);
String str;
char ch;
int count=0;
System.out.println("Enter the string:");
str=inp.nextLine();
while(str.length()>0)
{
count++;
str.substring(count);
}
System.out.println("Length :"+count);
}
}
Use a loop, calling nextLine() twice reads two lines (and throws them away) and don't close your Scanner. System.in is a global, if you close() your Scanner that will close System.in and it will not reopen.
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("Type your text...");
// System.out.println(sc.nextLine()); // <-- thrown away!
// System.out.println(sc.nextLine().length()); // <-- Second next line call
String line = sc.nextLine();
System.out.println("Length of String: " + lengthOfString(line)); // <-- not "hey"
// sc.close();
}
Edit
Just read lengthOfString(String), let's fix that -
private static int lengthOfString(String string) {
return string.trim().length();
}

Use of Scanner class in recursive functions

I am trying to use a recursive method/function, which uses the Scanner class. Closing the scanner, causes an exception to be thrown the next time the same method is called within the recursion. A workaround to this is not to close the scanner at all, but this is not a right approach. I suspect the same scanner object is used between recursive calls, so that's why closing it creates havoc. If my assumption is correct then closing the scanner in the last method call would be a valid workaround (i.e. no actual resource leak). Is there anything I may be missing before jumping into Scanner and related implementation code?
EDIT
The answers provided were really useful and enlightening. In summary, the problem is the constant re-opening and closing of the scanner, and not recursion per se. The reason I would avoid passing the scanner object as parameter is that this example simulates a larger project, calling multiple recursive functions and I would have to pass the scanner object in all of them.
On the practical side, and from the answers provided, I think just closing the scanner in the last recursive call would work without having any resource leaks. Any related opinions would be welcome, esp. if you see something wrong with my approach.
Here is an example of my initial experiment:
package scanner;
import java.util.Scanner;
public class Main {
public static void acceptValidInput() {
System.out.print("Enter a number greater than 10: ");
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
// Adding this will make an exception to be thrown:
sc.close();
if (i <= 10) {
acceptValidInput();
}
}
public static void main(String[] args) {
acceptValidInput();
System.out.println("Your input is valid");
}
}
Once you start to consume an input stream using a Scanner, you should not try to read from it in any other way anymore. In other words, after you have constructed a Scanner to read from System.in, you need to use it for all further reading from System.in. This is because Scanner buffers input, so you have no idea how much input it has already consumed but not emitted yet.
Therefore, I recommend that you construct one Scanner, then use it for all the reading:
public class Main {
public static void acceptValidInput(Scanner sc) {
System.out.print("Enter a number greater than 10: ");
int i = sc.nextInt();
if (i <= 10) {
acceptValidInput(sc);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
acceptValidInput(sc);
System.out.println("Your input is valid");
sc.close();
}
}
It works:
package scanner;
import java.util.Scanner;
public class Main {
public static void acceptValidInput(Scanner sc) {
int i = sc.nextInt();
if (i <= 10) {
System.out.print("Enter a number greater than 10: ");
acceptValidInput(sc);
}
}
public static void main(String[] args) {
System.out.print("Enter a number greater than 10: ");
Scanner sc = new Scanner(System.in);
acceptValidInput(sc);
sc.close();
System.out.println("Your input is valid");
}
}
The result is:
Enter a number greater than 10: 4
Enter a number greater than 10: 5
Enter a number greater than 10: 11
Your input is valid
Process finished with exit code 0
Closing the scanner closes also the underlying input stream. In this case it is the System.in stream - you shouldn't do this. Either do not close it or create a single scanner for all method calls.
public class abc{
public void acceptValidInput() {
System.out.print("Enter a number greater than 10: ");
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
// Adding this will make an exception to be thrown:
if (i <= 10) {
acceptValidInput();
}
}
public static void main(String[] args) {
while(true){
abc a=new abc();
a.acceptValidInput();
System.out.println("Your input is valid");
}
}}
try this.

Why does it not ask me for input?

import java.util.Scanner;
class Tutorial {
public static void main (String args[]){
System.out.println("Who goes there?");
Scanner name = new Scanner(System.in); ## I am asking for input form user but it does not take imput
if (name.equals("me") || name.equals("Me") ){
System.out.println("Well, good for you smartass.");
}else System.out.println("Well good meet");
}
}
Why does the program run the else and not ask for my input?
You should read your input by using scanner.nextLine():
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
if (name.equals("me") || name.equals("Me"))
{
System.out.println("Well, good for you smartass.");
} else {
System.out.println("Well good meet");
}
scanner.close();
You merely created a Scanner but did not tell it to read something from the standard input. You can do that by calling scanner.next() to read a token scanner.nextLine() to read a line, etc. As well you are comparing a Scanner to a String in the if-statement.
import java.util.Scanner;
class Tutorial {
public static void main (String args[]){
System.out.println("Who goes there?");
Scanner s = new Scanner(System.in);
String name = s.next(); // get the token
if (name.equals("me") || name.equals("Me") ){
System.out.println("Well, good for you smartass.");
} else System.out.println("Well good meet");
}
}
You've only created an instance of the Scanner object. You need to invoke a method such as Scanner#nextLine() to read input and then compare the read value to "me" or "Me".
Example:
Scanner name = new Scanner(System.in);
String input = name.nextLine();
if (...) // Compare input to something here.
You might want to use String#equalsIgnoreCase for case-insensitive matching too.

Categories

Resources