how to create multiple scanner elements in java [duplicate] - java

This question already has an answer here:
How to use multiple Scanner objects on System.in?
(1 answer)
Closed 26 days ago.
I have a main function in which I use scanner to read an integer from console.
Inside this main function, we can access another function which also uses scanner to read an integer. So, the program swings between these two functions many times. But, Java.util.scanner throws an exception. Is there any way to overcome this?
import java.util.Scanner;
public class dummy {
public static void main(String[] args) {
int buy;
Scanner sc = new Scanner(System.in);
buy = sc.nextInt();
user = dummy2();
sc.close();
}
static boolean dummy2(){
Scanner sc1 = new Scanner(System.in);
sc1.close();
}
}

First of all, it would make the question much easier to answer if you gave more information, such as the exception and its message, and maybe source code.
If the exception is a NoSuchElementException, the direct problem is that the function is closing the Scanner. When the scanner is closed, it also closes the underlying ImputStream. This makes all other Scanner on that input invalid.
If the exception is InputMismatchException, then the input is not an int.
If the exception is IllegalStateException, then the scanner has been closed, this could happen is the function and the main method are using the scanner, and one closes it.
However, you should not be taking user input in functions. This limits future use, say if you wanted to later add a GUI or make the same calculation based off a number not gotten from the user, then you would need rewrite the function. The function should take a int as a parameter, which the main method should get from the user. Only the main method and other methods directly relating to user input, such as the Scanner's methods, should read user input.

Use the same Scanner object.
import java.util.Scanner;
public class dummy {
private static final Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
int buy;
buy = sc.nextInt();
user = dummy2();
//Do more stuff with the same scanner
//close it when done
}
static boolean dummy2(){
//Scan stuff
int nbr = sc.nextInt();
}

I would suggest something like that:
import java.util.Scanner;
public class dummy {
Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
int buy;
buy = sc.nextInt();
user = dummy2();
sc.close();
}
static boolean dummy2(){
//lets scan a string.
sc.nextLine();
}
}
Reusable objects! Isn't that nice?

Related

How do I reuse my scanner?

I made a utility class with a method that is takes user input, and returns a lower case version of it so I don't have so much repetitive code, but it could only be used once. After that, it wouldn't scan. What can I do to fix this?
p.s. I have seen a lot of people saying it is a bad idea to reuse a scanner. Why is this? Shouldn't it be fine if the scanner is reset?
public String scan() {
String input;
Scanner s = new Scanner(System.in);
if (s.hasNextLine()) {
input = s.nextLine();
} else {
input = "ERROR";
}
s.reset();
s.close();
return input.toLowerCase();
}
You are correct every time you use the scanner its getting reseted. A solution to your problem would be the following:
Add all the parameters that you want to pass to scan() in an array and using a for loop pass them all to scan() while when returning, adding them again in their respective array position so then you can easily reuse them wherever you want.
You could actually reuse your Scanner instead of creating a new one each time you need to read a line , here is an example:
public class Test {
public static void main(String[] args) {
Test t = new Test();
//create your scanner object
Scanner s = new Scanner(System.in);
//send it as a parameter whenever you need to read a line
System.out.println(t.scan(s));
System.out.println(t.scan(s));
System.out.println(t.scan(s));
//close it after finishing
s.close();
}
public String scan(Scanner s) {
String input;
if (s.hasNextLine()) {
input = s.nextLine();
} else {
input = "ERROR";
}
return input.toLowerCase();
}
}
But if you make a reader utility class for you it's more logical to be an Instance variable in the utility class .
For Example:
public class Reader {
Scanner s ;
public Reader() {
s = new Scanner(System.in);
}
public String scan() {
String input;
if (s.hasNextLine()) {
input = s.nextLine();
} else {
input = "ERROR";
}
return input.toLowerCase();
}
public void close(){
s.close();
}
}
And when you use it , it will be like this :
public class Main {
public static void main(String[] args) {
//create your scanner object
Reader r = new Reader();
//send it whenever you need to read a line
System.out.println(r.scan());
System.out.println(r.scan());
System.out.println(r.scan());
//close it after finishing
r.close();
}
}
I have seen a lot of people saying it is a bad idea to reuse a
scanner. Why is this?
It is not a bad idea to reuse a scanner object in most cases. Without further context, it is hard to determine their reasons for saying that. It could've been they were mistaken. Maybe you reused it incorrectly when they stated that. Who knows?
One thing is certain: When you invoke Scanner#close() in an object that is reading from System.in, you are also closing the underlying input stream. And, once the input stream is closed, you cannot reopen it in the life of the application.
Shouldn't it be fine if the scanner is reset?
Scanner#reset() doesn't do what you think it does. In fact, in this code example it does nothing. This method resets the Locale to US, and the radix back to base 10.
Code Analysis
public String scan() {
String input;
Scanner s = new Scanner(System.in);
if (s.hasNextLine()) {
input = s.nextLine();
} else {
input = "ERROR";
}
s.reset();
s.close(); // BAD IDEA!!!!
return input.toLowerCase();
}
This method will only work one time for the reasons I already stated: "once the input stream is closed, you cannot reopen it in the life of the application." So, what you do instead? If you require to reuse this Scanner object over and over, it might be better to make it a global attribute of the class and you should never close it. This is obviously a bad idea. So, you might be better off using some other type of input stream wrapper.
Maybe this is why other people have told you in the past that reusing the scanner object was a bad idea. It is only speculation. But, judging from this code example, it seems like a very strong possibility.

How do I make a method work in my class in Java [duplicate]

This question already has answers here:
How to call a method in another class of the same package?
(8 answers)
Closed 7 years ago.
Hi I have a robot which I need to tell it to move a certain number of times forward by saying forward 5. I have the method, I just need to get it to work in my class. Here is the method:
public void moveNumOfTimes(int num)
{
//-----------------------------------------------------------------------------------------------
int i=0;
while(i<num) {
if (this.frontIsClear()){ // if the front is NOT clear the robot should not move, otherwise will collide into the wall
this.move();
}
i++; // same as i=i+1;
}
//-----------------------------------------------------------------------------------------------
}
How do I enter that in my program? Is it like this?
moveNumOfTimes(int num);
Hope someone can help. Thanks
You should use a Scanner object to take input from the console.
Scanner sc = new Scanner(System.in);
You can implement like this.
class Robot{
public static void main(String args[]){
Scanner sc = new Scanner();
int numOfSteps = sc.nextInt(); //This line takes a integer input from the user
YourClassName r = new YourClassName();
//DO any initialization operations here
r.moveNumOfTimes(numOfSteps);
//Post movement operations come here
}
You can learn more on scanner here
How do I enter that in my program? Is it like this?
moveNumOfTimes(int num);
Yes, you could use something similar to this if you were trying to pass a command in from another method call. Something like:
public void Control(int moveNumber) {
... some other code, do some other stuff...
moveNumOfTimes(moveNumber); //Here you are passing a parameter value to your original method;
}
Or you could control it directly with another method like:
public void moveFive() {
moveNumOfTimes(5);
}
More likely, however, you wouldn't want to hardcode a method but rather call your original method directly through your Main method.
public static void main(String [ ] args) {
Robot r = new Robot();
r.moveNumOfTimes(5); //Here you have moved your new robot!
}
And if you really want to get fancy, look into working with the System and Scanner classes so you can prompt your user to tell the robot how much to move:
public static void main(String [ ] args) {
Robot r = new Robot();
Scanner reader = new Scanner(System.in);
System.out.println("How far should the robot move?"); //Output to the console window
int input = reader.nextInt(); //Reads the next int value
r.moveNumOfTimes(input); //Calls your method using the scanned input
}

Scanner is requiring me to type inputs twice just for one to register

I've been doing a ton of research on this for the past few hours, with no luck. I am pretty sure this is a problem with .next() or .nextLine() (according to my searches). However, nothing has helped me solve my problem.
When I run the code below, I have to type in input twice, and only one of the inputs is subsequently added to the arrayList (which can be seen when you print the contents of the arrayList).
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
public class Tester{
public static void main(String[] args) {
AddStrings();
}
public static void AddStrings() {
Scanner console = new Scanner(System.in);
ArrayList<String> strings = new ArrayList<String>(); //this arraylist will hold the inputs the user types in in the while loop below
while(true) {
System.out.println("Input file name (no spaces) (type done to finish): ");
if(console.next().equals("done")) break;
//console.nextLine(); /*according to my observations, with every use of .next() or .nextLine(), I am required to type in the same input one more time
//* however, all my google/stackoverflow/ reddit searches said to include
//* a .nextLine() */
//String inputs = console.next(); //.next makes me type input twice, .nextLine only makes me do it once, but doesn't add anything to arrayList
strings.add(console.next());
}
System.out.println(strings); //for testing purposes
console.close();
}
}
Problem with your code is that you are doing console.next() two times.
1st Inside if condition and
2nd while adding to ArrayList.
Correct Code :
public class TestClass{
public static void main(String[] args) {
AddStrings();
}
public static void AddStrings() {
Scanner console = new Scanner(System.in);
ArrayList<String> strings = new ArrayList<String>(); //this arraylist will hold the inputs the user types in in the while loop below
while(true) {
System.out.println("Input file name (no spaces) (type done to finish): ");
String input = console.next();
if(input.equals("done")) break;
strings.add(input);
System.out.println(strings);
}
System.out.println(strings); //for testing purposes
console.close();
}
}
In your code, you are asking for two words to be inserted. Just remove one of them.
Use it this way:
String choice = console.next();
if (choince.equals('done')) break;
strings.add(choice);

How to convert an array to regular method

I am trying to write this code for a class, but I don't want to use an array (String word[]). How do I change it so I use a regular method with parentheses?
Also, one of my friends helped and I am trying to learn, and I forgot what the alright(s); thing does. I tied to figure it out, but have failed. I think it creates and object for the scan, but I don't really know.
import java.util.Scanner;
public class WordLines{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
alright(s);
}
public static void alright(String s){
String word[]=s.split(" ");
for(int j=0;j<word.length; j++){
System.out.println(word[j]);
}
}
}
Thank you so much for the help!!! :)
One way to achieve similar results without the array is to use an additional instance of the Scanner class to parse the string:
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
Scanner parse = new Scanner(s);
while (parse.hasNext()) {
System.out.println(parse.next());
}
Link: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

Select a function depending upon the input in java

If I have the two functions below.
How can I select the function that will be chosen?
I imagine there is either some form of statement to determine the content of the scanner and therefore only have one function. Or it would be something that is passed to the function.
public static int questionAsk(String question)
{
Scanner scan = new Scanner (System.in);
System.out.print (question+"\n");
System.out.print ("Answer: ");
return scan.nextInt();
}
public static String questionAsk(String question)
{
Scanner scan = new Scanner (System.in);
System.out.print (question+"\n");
System.out.print ("Answer: ");
return scan.nextLine();
}
There is no way for the compiler to know which one of those methods you are calling. You could make it type safe by changing the String Types to something else, like this:
public static int questionAsk(IntQuestion question)
{
Scanner scan = new Scanner (System.in);
System.out.print (question.toString() +"\n");
System.out.print ("Answer: ");
return scan.nextInt();
}
public static String questionAsk(StringQuestion question)
{
Scanner scan = new Scanner (System.in);
System.out.print (question.toString() +"\n");
System.out.print ("Answer: ");
return scan.nextLine();
}
And adding two new classes:
public class IntQuestion extends String{
public IntQuestion(String question){
super(question);
}
}
public class StringQuestion extends String{
public StringQuestion(String question){
super(question);
}
}
When you construct an IntQuestion of StringQuestion, you can simply construct them the same way you would construct a String if you called the constructor:
IntQuestion intQuestion = new IntQuestion("Some String Here");
This is just a little bit of syntactic sugar to get the compiler to play nice and select the correct method based on the type.
I hope this helps.
You should first scan, parse and then call the required function using if else or switch case.
What you are doing right now is using the same code in two functions, and not reusing the code. Just use a single scan instead

Categories

Resources