5

I was making a program to reduce given integers to their simplest ratio.But an error is occurring while taking inputs through Scanner class in a sub-method of program.Here is the code :

package CodeMania;

import java.util.Scanner;

public class Question5 
{
public static void main(String args[])
{
    Scanner sc=new Scanner(System.in);
    int T=sc.nextInt();// number of test cases
    sc.close();
    if(T<1)
    {
        System.out.println("Out of range");
        System.exit(0);
    }
    for(int i=0;i<T;i++)
    {
    ratio();//line 19
    }

}
static void ratio()
{
    Scanner sc1=new Scanner(System.in);
    int N=sc1.nextInt();//line 26
    if((N>500)||(N<1))
    {
        System.out.println("Out of range");
        System.exit(0);
    }
    int a[]=new int[N];
    for(int i=0;i<N;i++)
    {
        a[i]=sc1.nextInt();
    }
    int result = a[0];
   for(int i = 1; i < a.length; i++)
        {
    result = gcd(result, a[i]);
    }
    for(int i=0;i<N;i++)
    {
        System.out.print((a[i]/result)+" ");
    }
    sc1.close();
}
static int gcd(int a, int b)
{
    while (b > 0)
    {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}
}

The error is--

Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:862)
    at java.util.Scanner.next(Scanner.java:1485)
    at java.util.Scanner.nextInt(Scanner.java:2117)
    at java.util.Scanner.nextInt(Scanner.java:2076)
    at CodeMania.Question5.ratio(Question5.java:26)
    at CodeMania.Question5.main(Question5.java:19)

Here I have used 2 seperate scanner objects sc in main function and sc1 in ratio function to take input from console. However if I am declaring a public static type Scanner object in class scope and then using only one Scanner object throughout the program to take input then program is working as required without error.

Why this is happening...?

Suyash Tilhari
  • 123
  • 2
  • 10
  • See [this answer](http://stackoverflow.com/questions/4232588/how-to-use-multiple-scanner-objects-on-system-in), I think you have the same problem. – Alin Pandichi Dec 29 '15 at 10:21

4 Answers4

5

The reason for this error is that calling .close() on the scanner also closes the inputStream System.in, but instantiating a new Scanner will not re-open it.

You need to either pass a single Scanner around in your method parameters, or make it a static global variable.

Remi
  • 151
  • 3
  • I knew that I need to pass single scanner for whole program.But I didn't know why I can't use multiple Scanners....Thanks for the reason. – Suyash Tilhari Jan 13 '16 at 18:29
0

Since your main() and your ratio() method are using Scanners they throw exceptions,when an Exception occurs the normal flow of the program is disrupted and the program/Application terminates abnormally, which is not recommended, therefore these exceptions are to be handled. An exception can occur for many different reasons, below given are some scenarios where exception occurs.

A user has entered invalid data.

A file that needs to be opened cannot be found.

A network connection has been lost in the middle of communications or the JVM has run out of memory.

You can handle these exceptions by using Try/Catch blocks,or you can handle them by using the word throws after your method's definition, in your case these two approaches are going to be like this:

With Try/Catch :

  public static void main()
  {
    try{
        Scanner sc=new Scanner(System.in);
        int T=sc.nextInt();// number of test cases
        sc.close();
       }
    catch(NoSuchElementException e){
    System.out.print("Exception handled" + e);
    //rest of method
    }
    static void ratio(){
    try{
    Scanner sc1=new Scanner(System.in);
    int N=sc1.nextInt();}
    catch(NoSuchElementException e){
    System.out.print("Exception handled" + e);}
    //rest of method
    }

With "throws":

  public static void main()throws Exception{

       //rest of method
     }
   static void ratio()throws Exception
   { 
    //rest of method
   }
pouyan021
  • 177
  • 1
  • 4
  • 19
0

Try this one. You can pass the scanner as argument

package stack.examples;

import java.util.Scanner;

public class Question5 {
public static void main(String args[]) {
    Scanner sc = new Scanner(System.in);
    int T = sc.nextInt();// number of test cases
    if (T < 1) {
        System.out.println("Out of range");
        System.exit(0);
    }
    for (int i = 0; i < T; i++) {
        ratio(sc);// line 19
    }
    sc.close();
}

static void ratio(Scanner sc1) {
    int N = sc1.nextInt();// line 26
    //Your Logic
}

static int gcd(int a, int b) {
    while (b > 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

}

0
import java.util.*;
public class Understanding_Scanner
{
public static void main()
{
Scanner sc= new Scanner(System.in);
System.out.println("Please enter your name");
String name=sc.next();
System.out.println("Your name is:"+name);
}
}

Now to explain this thing so we have to import a scanner class from the Java Utility package so this can be achieved by the code on the first line the second line is creating a class NOTE (THE NAME OF THE CLASS NEED NOT START WITH CAPITAL) now coming to the main topic Scanner class so for this we must create a scanner class within the program with the code that's been given in the 4th line... in this statement 'sc' is an object which stores the values of the scanner class so if you want to do any operation in the scanner class you can do it via the object 'sc' *NOTE(You can name ur object as anything eg:poop,bla etc)... then we have this interesting command which says System.in now this allows users to write any statement through the keyboard or any such input devices during run time.... String name=sc.next() this line helps us to write any string that we want to write during the run time, which will b stored in the name variable

So that's it, this is the scanner class for u. Hope its easy to understand.

cheers!! Keep coding :-)