Scanner Cannot be Dereferenced - java

My issue is to create a method called getScanner, and each time it is called, another method can call getScanner to get the next line of input.
Code:
public static void getScanner() {
Scanner input = new Scanner(System.in);
}
public static String getInput() {
String userInput = getScanner().nextLine();
return userInput
}
Error
error: void cannot be dereferenced
String userInput = getScanner().nextLine();
1 error
Essentially, I have multiple methods that need to user Scanner as input, rather than declaring a global or local variable, I want to call one method that will create a Scanner as input each time it is called and assign a variable to this input.

You have set void return type which returns nothing. Since you require a scanner object, return a Scanner in the method.
public static Scanner getScanner() {
Scanner input = new Scanner(System.in);
return input }
public static String getInput() {
String userInput = getScanner().nextLine();
return userInput }

You are not returning an instance of Scanner. Use:
public static Scanner getScanner(){
return new Scanner(System.in);
}

Working Code. Tested and Compiled.
public class testj
{
public static void main(String[] args)
{
System.out.println(getInput());
}
private static String getInput()
{
String userInput = getScanner().nextLine();
return userInput;
}
private static Scanner getScanner()
{
return new Scanner(System.in);
}
}
We have to specify in the method header, what object is getting returned.
Shorter version for getInput()
You can also modify this method as below
private static String getInput()
{
return getScanner().nextLine();
}

Related

Exception when I insert a different Scanner in different methods

In the main method, I create an object cls and call its method test. This method will call two others methods (test1 and test2). Each one has its Scanner.
public static void main(String[] args) {
Class2 cls = new Class2();
cls.test();
}
the Class2 is:
public class Class2 {
public Class2() {
}
public void test()
{
test2();
test3();
}
public void test2() {
Scanner scanner = new Scanner(System.in);
System.out.println("give a String:");
String str = scanner.next();
scanner.close();
}
public void test3()
{
Scanner sc = new Scanner(System.in);
System.out.println("give another String:");
String str = sc.next();
sc.close();
}
}
After execution, I got an exception
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1478)
at Class2.test3(Class2.java:25)
at Class2.test(Class2.java:11)
at Class1.main(Class1.java:12)
How can I handle this exception please ? by keeping in each method a different scanner !
Here Is your rectified code with appropriate comments.
Class2.java
import java.util.Scanner;
public class Class2 {
/*You dont have to create multiple scanner objects*/
Scanner scan = new Scanner(System.in);
public void test() {
/*In order to run the methods in this class itself
* you have to use static keyword or create object*/
Class2 obj = new Class2();
obj.test2();
obj.test3();
scan.close();
/* As this method is run, scan.close() should be placed when you want to close InputStream
* you will learn this in Java Streams*/
}
public void test2() {
System.out.println("give a String:");
String str = scan.nextLine();
}
public void test3() {
System.out.println("give another String:");
String str = scan.nextLine();
}
}
Main.java
public class Main {
public static void main(String[] args) {
Class2 cls = new Class2();
cls.test();
}
}
Why did the error occur?
Ans: When your code executes test2() method it closes the scanner InputStream in the ending by using scan.close(), hence when the test3() is executed it can no longer read data. The solution is that you either close scanner in the test3() method or in the test() method.

How can I test multiple inputs from console?

I need to test input from console in my program:
Main.java - class with main logic.
public class Main {
public static void main(final String[] args) {
final Integer dividend = new IntegerReader().fetchIntegerNumber("Input dividend: ");
final Integer divisor = new IntegerReader().fetchIntegerNumber("Input divisor: ");
System.out.println(dividend);
System.out.println(divisor);
}
}
IntegerReader.java - reads integer number from input.
import java.util.Scanner;
public class IntegerReader {
public Integer fetchIntegerNumber(final String message) {
System.out.print(message);
final Scanner scanner = new Scanner(System.in);
final String inputString = scanner.nextLine();
scanner.close();
return Integer.valueOf(inputString);
}
}
MainTest.java - test of Main.java class.
class MainTest {
private final InputStream testInputStream = new ByteArrayInputStream("2\n3".getBytes());
private final ByteArrayOutputStream testOutputStream = new ByteArrayOutputStream();
private InputStream initialInputStream = System.in;
private PrintStream initialOutputStream = System.out;
#BeforeEach
void setUpStreams() {
System.setIn(testInputStream);
System.setOut(new PrintStream(testOutputStream));
}
#AfterEach
void restoreDefaultStreams() {
System.setIn(initialInputStream);
System.setOut(initialOutputStream);
System.out.println("Test initial output stream");
}
#Test
void fetchesTextFromInput() {
Main.main(new String[]{});
final String actual = testOutputStream.toString();
assertThat(actual, is("Input dividend: Input divisor: 2\n3"));
}
}
When I run test, I get exception: java.util.NoSuchElementException: No line found.
This exception is thrown, if I try to read second number (divisor) on line:
final String inputString = scanner.nextLine();
How can I fix test, so that exception will not occur?
I would design the IntegerReader in the way that it accepts a scanner:
public class IntegerReader {
private final Scanner scanner;
public IntegerReader(Scanner theScanner) {
this.scanner = theScanner;
}
public Integer fetchIntegerNumber(final String message) {
System.out.print(message);
final String inputString = scanner.nextLine();
return Integer.valueOf(inputString);
}
}
The main class would look like this:
public class Main {
private Scanner scanner;
public Main(Scanner theScanner) {
this.scanner = theScanner;
}
public static void main(final String[] args) {
new Main(new Scanner(System.in)).process();
}
public void process() {
final Integer dividend = new IntegerReader(scanner).fetchIntegerNumber("Input dividend: ");
final Integer divisor = new IntegerReader(scanner).fetchIntegerNumber("Input divisor: ");
System.out.println(dividend);
System.out.println(divisor);
}
}
The test then looks the following way:
// this test still fails, but. ..
public class MainTest {
private final InputStream testInputStream = new ByteArrayInputStream("2\n3\n".getBytes());
private final ByteArrayOutputStream testOutputStream = new ByteArrayOutputStream();
private PrintStream initialOutputStream = System.out;
#Before
public void setUpStreams() {
System.setOut(new PrintStream(testOutputStream));
}
#After
public void restoreDefaultStreams() {
System.setOut(initialOutputStream);
System.out.println("Test initial output stream");
}
#Test
public void fetchesTextFromInput() {
Scanner scanner = new Scanner(testInputStream);
Main main = new Main(scanner);
main.process();
final String actual = testOutputStream.toString();
Assert.assertEquals("Input dividend: Input divisor: 2\n3", actual);
}
}
In this way the scanner is not closed.
Note that the test is not green. I used JUnit, I don't know which technology you used.
Please note:
If I design a class I would not make it dependend on System.*, but give it some stream to work with. This eases testing.
if you use new anywhere in your code you need to know whether the class has the concern to do this or if someone else, a builder or factory should rather create this instance.
You don't want to invoke scanner.close(); because Scanner.close() will close the underlying Closable instance, here System.in and so your dummy test inputstream will be discarded.
Besides even by removing the explicit closing operation it will still fails at runtime :
public Integer fetchIntegerNumber(final String message) {
System.out.print(message);
final Scanner scanner = new Scanner(System.in);
final String inputString = scanner.nextLine();
// REMOVED scanner.close();
return Integer.valueOf(inputString);
}
because the method return will make the scanner eligible to be GC and so System.in will still be closed.
What you want is that System.in.close() be not invoked.
You have two simple ways : Prevent this invocation from the scanner instance or from the underlying resource instance directly (System.in).
You could decorate System.in with FilterInputStream.
For example :
InputStream inWithoutClose = new FilterInputStream(System.in) {
#Override
public void close() throws IOException {
}
}
Then modify the method to test to make it accept this object.

java Scanner declaring

i tried to declare a new scanner, it works fine but only at the main.
when i write methods (out of the main of course) it wont recognize the scanner.
import java.util.Scanner;
public class Exe1GenericSort {
public static void main(String[] args) {
Scanner input= new Scanner(System.in);
start();
int i = input.nextInt();
}//end main
here it works fine, but at the method "start" it wont let me use "input.next....
tried to write the "Scanner input = new Scanner.... above the main and still wont work...
You need to declare the Scanner as an object outside the main function and then you can use it in other functions.
import java.util.Scanner;
class ScannerTest {
private static Scanner scanner;
public static void main(String[] args){
scanner = new Scanner(System.in);
start();
}
private static void start(){
String input = scanner.nextLine();
System.out.println("Input: " + input);
}
}
NOTE: The scanner object as well as the start function need to be static in order for you to access them inside the main function.
public static void main(String[] args) {
Scanner input= new Scanner(System.in);
int x= start(input);
System.out.println("enter another number");
int i = input.nextInt();
System.out.println("a number:"+x);
System.out.println("another number"+i);
}
public static int start(Scanner scan)
{
System.out.println("Please enter a number");
int x = scan.nextInt();
return x;
}
to use Scanner in another method
accept a parameter in the method start() and then return x to test the value then print the value in the main method
solved:
import java.util.Scanner;
public class Exe1GenericSort {
static Scanner input = new Scanner (System.in);
public static void main(String[] args) {
this one works great !
thank for help ppl.
problem solved ! :)

Java Check user input against variables in another class

I am building an easy Knock Knock game. I have it finished but I would like to add a small feature. It is currently set to accept only a few words/phrases as the correct response and everything else it produces an "error" of sorts. I want to create a class with a list of acceptable works or phrases and have the users input checked against that class.
Here is the test class I created to play with.
import java.util.*;
public class test
{
static Scanner sc = new Scanner(System.in);
public static void main(String[] args)
{
System.out.println("Choose a word");
String userEntry = sc.next().toLowerCase();
if (userEntry.equals(test1.*))
{
System.out.println("We found a match");
}
else if (!userEntry.equals(test1.*))
{
System.out.println("We did not find a match");
}
}
}
The code is of the class that will house the variables.
public class test1
{
public static String a = "yes";
public static String b = "hello";
public static String c = "boo";
}
In the first class, I tried using a wild card to call all of the variables in the class but it produces an error. Any help would be greatly appreciated.
You can't do a wildcard search like that in Java.
You really don't need another class, you can just put all the words/phrases in a List and check against the List.
Example:
import java.util.*;
public class test
{
static Scanner sc = new Scanner(System.in);
// add all the words you need into this array
static String [] wordArr = new String[] { "yes", "hello", "boo" };
// this converts the array to a List
static final List<String> WORDS
= new ArrayList<String>(Arrays.asList(wordArr));
public static void main(String[] args)
{
System.out.println("Choose a word");
String userEntry = sc.next().toLowerCase();
// check if the word is in the list
if (WORDS.contains(userEntry))
{
System.out.println("We found a match");
}
else
{
System.out.println("We did not find a match");
}
}
}
Side Note: You should consider creating the Scanner in the main method and close the scanner when you are done with it.
try this
class test1
{
public static list<String> addElement(){
List<String> list=new ArrayList<>();
list.add("yes");
list.add("boo");
list.add("hello");
}
}
class test{
public static void main(String[] args0)
{
Scanner sc=new Scanner(System.in);
String match=sc.next();
ArrayList<String> list=test1.addElement();
for(String test : list)
{
if(test.equels(match)
print("we have found match");
else
print("no match found"):
}
}
}

How to use method showMessage()?

In class we learned about methods, but I'm having a bit of trouble using them.
In a package called util, I wrote a class called IO.
public class IO {
public static float getFloat(){
String str = JOptionPane.showInputDialog("Enter a real number");
return Float.parseFloat(str);
}
public static void showMessage(Scanner s){
System.out.println(s);
JOptionPane.showMessageDialog(null, s);
}
public static Scanner getInput (String prompt){
String s = JOptionPane.showInputDialog(prompt);
return new Scanner(s);
}
}
Also in package util, I have my program, called Program 4.
public class Program4 {
public static void main(String[] args) {
IO.getInput("enter 2 integers");
IO.showMessage(Scanner(s));
}
}
What I don't understand is how do I display the 2 integers entered? One is a scanner object and one is string. How do I use the method getInput to show convert the scanner into a string? Am I going to have to write a new method and use parse?
You can get user input without using Scanner. Here is example:
IO Class
public class IO {
public static float getFloat() {
String str = JOptionPane.showInputDialog("Enter a real number");
return Float.parseFloat(str);
}
public static void showMessage(String s) {
System.out.println(s);
JOptionPane.showMessageDialog(null, s);
}
public static String getInput(String prompt) {
// JOptionPane.showInputDialog() return user input String
String input = JOptionPane.showInputDialog(prompt);
return input;
}
}
Program4 Class
public class Program4 {
public static void main(String[] args) {
// IO.getInput() return stored input String
String input = IO.getInput("enter 2 integers");
IO.showMessage(input);
}
}

Categories

Resources