How to input values to a scanner multiple times? - java

I'm trying to make a small program to help with my homework. It needs to square a number that is input and then sum all the squares and display them.
I came up with this but I have been getting errors.
import java.util.Scanner;
public class Statistics {
public static void main(String[] args) {
int sum = 0;
Scanner scan = new Scanner(System.in);
Scanner input = new Scanner(System.in);
System.out.println("\nHow many times? ");
int times = scan.nextInt();
scan.close();
for(int i = 0; i < times; i++) {
System.out.println("\nEnter the number to be squared: ");
int squ = input.nextInt();
System.out.println(squ + "\n\n");
sum += squ;
}
input.close();
System.out.println("\n\nSum = " + sum);
}
}
Here's the error I've been getting in the Eclipse console:
> Exception in thread "main" java.util.NoSuchElementException
> at java.util.Scanner.throwFor(Unknown Source)
> at java.util.Scanner.next(Unknown Source)
> at java.util.Scanner.nextInt(Unknown Source)
> at java.util.Scanner.nextInt(Unknown Source)
> at Statistics.main(Statistics.java:16)
Any help would be greatly appreciated.

When you close a Stream, it closes the underlying stream as well.
You almost never need to close System.in and I don't suggest you do it in this case.
You should avoid wrapping the same stream more than once, unless you like confusion. Unfortunately there is no simple way to prevent a developer from doing this but it is almost always a bug.
In short, you don't need to wrap System.in stream twice and in fact it will fix your problem.
This is how it might be written
Scanner scan = new Scanner(System.in);
System.out.println("\nHow many times? ");
int times = scan.nextInt();
double sum = 0;
for(int i = 0; i < times; i++) {
System.out.println("\nEnter the number to be squared: ");
double d = input.nextDouble();
double squ = d * d;
System.out.println(squ + "\n\n");
sum += squ;
}
System.out.println("\n\nSum = " + sum);

Use only one scanner, you don't need a second one.
Something like this:
import java.util.Scanner;
public class Statistics {
public static void main(String[] args) {
int sum = 0;
Scanner scan = new Scanner(System.in);
System.out.println("\nHow many times? ");
int times = scan.nextInt();
for(int i = 0; i < times; i++) {
System.out.println("\nEnter the number to be squared: ");
int squ = scan.nextInt();
System.out.println(squ + "\n\n");
sum += squ;
}
scan.close();
System.out.println("\n\nSum = " + sum);
}
}

Put the close of your first scanner to the close to the second one after for-loop.
Thats because your input-stream is closed with the first close and the second scanner cannot work.

Related

How to use Scanner in both main and method

I'm trying to get input in both my main and other methods, but I'm not clear on how to get the scanner working in both.
It gives me a weird error:
Exception in thread "main"
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextDouble(Unknown Source)
at Hwk11.getRainData(Hwk11.java: 28)
at Hwk11.main(Hwk11.java: 18)
Code:
import java.util.Scanner;
public class Hwk11 {
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
System.out.println("How many weeks of data do you have?");
int numWeeks = stdin.nextInt();
if (numWeeks <= 0 || numWeeks > 52) {
System.out.println("Invalid number of weeks.");
}
else {
double[] rainWeeks = new double [numWeeks];
getRainData(rainWeeks);
showRain(rainWeeks);
}
}
public static void getRainData(double[] rainFall) {
Scanner stdin = new Scanner(System.in);
System.out.println("Enter the weekly rainfall for each week.");
for (int index = 0; index < rainFall.length; index++) {
System.out.println("Week number " + (index + 1) + ":");
rainFall[index] = stdin.nextDouble();
}
}
public static void showRain(double[] rainFall) {
for (int index = 0; index < rainFall.length; index++) {
System.out.print(rainFall[index] + " ");
}
}
}
People are saying "works for me".
The problem that the behavior (whether it works or not) depends on exactly how input is provided.
If you provide input interactively, it will probably work.
If you provide input by redirecting standard input like this:
java Hwk11 < input.txt
then it won't.
The problem is that a Scanner will read-ahead and buffer any characters available from its input stream. That is fine normally, but in your code you have created two distinct Scanner objects to read from System.in. Thus when standard input is redirected:
The first Scanner.nextInt call will cause most / all of the input to be buffered in the first Scanner
When the second Scanner is created and Scanner.nextDouble is called, it won't see the input buffered in the first Scanner and that will lead to an exception ... when it runs out of input characters "too soon".
The solution is to NOT create multiple Scanner objects for the same input stream. Use one Scanner and either put it in a field, or pass it as a parameter to all of the places that it needs to be used.
Works for me. Don't enter anything but a double if you asking for next double so no "2.3 cm", just pass 2.3 and add cm when you print in
I am assuming your showRain(double[] rainFall) method probably executes before getRaindata(double[] rainFall) is able to finish and populate the array. Array you passsing to showRain(double[] rainFall) might be empty.
Try putting your method call for showRain(double[] rainFall) after loop in getRanData(double[] rainFall)
Alternitivly try passing the whole Scanner object to method.
public static void getRainData(double[] rainFall, Scanner stdin) {
//Scanner stdin = new Scanner(System.in);
System.out.println("Enter the weekly rainfall for each week.");
for (int index = 0; index < rainFall.length; index++) {
System.out.println("Week number " + (index + 1) + ":");
rainFall[index] = stdin.nextDouble();
}
showRain(rainFall);
}
Don't forget to close it when you done with scanner.

JAVA : "java.util.InputMismatchException" error

new programmer here, just trying to finish my programming assignment (last one of the semester)!
Basically, assignment is as follows: Write a program that reads integers, finds the largest of them, and counts its occurrences. Assume the input ends with 0.
My code:
import java.util.Scanner;
public class IntCount {
public static void main(String[] args) {
int max;
int count = 1;
int num;
int test = 1;
Scanner scan = new Scanner(System.in);
System.out.println("Please enter integers");
num = scan.nextInt();
String[] testNums = Integer.toString(num).split("");
max = Integer.parseInt(testNums[0]);
System.out.println("TEST MAX = " + max);
int leng = testNums.length;
while (leng != 1) {
if ((Integer.parseInt(testNums[test])) == max) {
count++;
}
if ((Integer.parseInt(testNums[test])) > max) {
max = Integer.parseInt(testNums[test]);
}
leng = leng - 1;
test = test + 1;
}
System.out.println(java.util.Arrays.toString(testNums));
if (leng == 1) {
System.out.println("Your max number is: " + max);
System.out.println("The occurances of your max is: " +count);
} else {
System.out.println("Your max number is: " + max);
System.out.println("The occurrences of your max is: " + count);
}
}
}
Code will work fine for input such as: 3525550 (max number is 5, occurrences is 4)
Code will not work for input such as: 36542454550
For this iput, I receive the following error:
Exception in thread "main" java.util.InputMismatchException: For input string: "36542454550"
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at IntCount.main(IntCount.java:13)
No idea how to fix this and its driving me nuts!! not looking for direct answer, as I wouldn't learn anything, but maybe some guidance on what to do next. Thank you all ahead of time!
Integers have a max value of 2147483647. The number in your input bigger. Scan for a long instead of int.
Alternatively, scan for a String (since you're already converting your Integer to a string).
36542454550 is too big of a number to hold in an int
Try using double or long
The max value for a signed integer is 2147483647
I recommend you to use bigInteger in this kind of situations, you can see more information about bigIntegers here: BigIntegers
Here's an example of a program that does what you described:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
SortedMap<Long, Integer> maxMap = new TreeMap<>();
Long newLong = null;
do {
System.out.println("Please Enter a Integer: ");
newLong = scan.nextLong();
int count = maxMap.containsKey(newLong) ? maxMap.get(newLong) : 0;
maxMap.put(newLong, ++count);
} while (newLong.intValue() != 0);
System.out.println("Max number is: " + maxMap.lastKey());
System.out.println("Count: " + maxMap.get(maxMap.lastKey()));
scan.close();
}

While loop with hasNext(); not fully looping

I'm in the process of creating a program that reads data from an external file, compares it with other data within the file then prints the results to a new external file. I am having problems with the while loop section of my code. I am unsure whether it is the while loop itself or the for loop which is nested within. Here is the code:
public class WageCalculator {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new FileReader("TestData.txt")); //Scanner for external file
PrintWriter output = new PrintWriter("wagedaily.txt");
float RecommendedMaximum;
RecommendedMaximum = Float.parseFloat(JOptionPane.showInputDialog(null, "Enter the recommended maximum journey cost:"));
String ShipID, JourneyID; //Variables
int JourneyLength, Crew;
double RateOfPay, CrewCost, TotalCost;
while (input.hasNext()) { //EOF-Controlled While Loop
ShipID = input.nextLine();
JourneyID = input.nextLine();
JourneyLength = input.nextInt();
Crew = input.nextInt();
CrewCost = 0; //Default Values Set
TotalCost = 0;
for (int x = Crew; x > 0; x--) { //For Loop updates the above values
RateOfPay = input.nextDouble();
CrewCost = RateOfPay * JourneyLength;
TotalCost = TotalCost + CrewCost;
}
if (TotalCost < RecommendedMaximum) { //if-else statements to compare values
System.out.println("The total cost of...");
output.println("The total cost of...");
} else if (TotalCost == RecommendedMaximum) {
System.out.println("The total cost of...");
output.println("The total cost of...");
} else {
System.out.println("The total cost of...");
}
}
output.close(); //Close both Scanner and Printwriter
input.close();
}
}
The error I get is this:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at (package).WageCalculator.main(WageCalculator.java:30)
The error says it's line 30 in my code that is the problem but I am not so sure.
Incase anyone needs to see the TestData.txt file:
Monarch //ShipID
M141 //JourneyID
16 //JourneyLength
6 //Crew
10.5 //RateOfPay -
10.5
20
20
20
30 //- RateOfPay
Princess //ShipID
P103 //JourneyID
18 //JourneyLength
5 //Crew
40 //RateOfPay -
45
45
60
80 //- RateOfPay
Any help would be appreciated :)
You're making a bunch of input.nextXXX() calls within the loop after checking input.hasNext() only once at the top of the loop. Don't do that as this is very unsafe and bound to fail and as there should always be a one-to-one correspondence between a check and a get. For instance, if you want to get a next line, there should be one input.HasNextLine() called before calling calling input.nextLine(). Same for input.next() or input.nextInt().
Myself, I'd read line by line by checking hasNextLine() and then once reading in the nextLine(), and then manipulating the String received.
while (input.hasNextLine()) {
String line = input.nextLine();
// now do not use input further within the loop
}
You could then within the loop use a second Scanner using the line received, or split the line via String#split(String regex) or do whatever you need to do with it.
Or you could use String replaceAll(...) and regular expressions to get rid of all white space followed by "//" followed by any chars. e.g.,
while (input.hasNextLine()) {
String line = input.nextLine();
// get rid of white space followed by "//" followed by anything
line = line.replaceAll("\\s+//.*", "");
System.out.println(line);
}
Edit
I've looked a bit more into your question and your data, and I am going to amend my answer. If you're absolutely sure of the integrity of your data file, you could consider checking for nextline once per obtaining data of an entire ship. For example:
public static void main(String[] args) {
InputStream inStream = GetData.class.getResourceAsStream(DATA_FILE);
List<Cruise> cruiseList = new ArrayList<>();
Scanner input = new Scanner(inStream);
while (input.hasNext()) {
String name = getLine(input);
String id = getLine(input);
int length = Integer.parseInt(getLine(input));
int crew = Integer.parseInt(getLine(input));
// assuming a class called Cruise
Cruise cruise = new Cruise(name, id, length, crew);
for (int i = 0; i < crew; i++) {
cruise.addPayRate(Double.parseDouble(getLine(input)));
}
cruiseList.add(cruise);
}
input.close();
}
private static String getLine(Scanner input) {
String line = input.nextLine();
// get rid of white space followed by "//" followed by anything
line = line.replaceAll("\\s+//.*", "");
return line;
}
The reason it gives you trouble is because when the user enters an integer then hits enter, two things have just been entered - the integer and a "newline" which is \n. The method you are calling, "nextInt", only reads in the integer, which leaves the newline in the input stream. But calling nextLine() does read in newlines, which is why you had to call nextLine() before your code would work. You could have also called next(), which would also have read in the newline.
Also read the Documentation of Scanner class for further understanding :
Here is the Corrected Code :
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class WageCalculator {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new FileReader("TestData.txt")); //Scanner for external file
PrintWriter output = new PrintWriter("wagedaily.txt");
float RecommendedMaximum;
RecommendedMaximum = Float.parseFloat(JOptionPane.showInputDialog(null,
"Enter the recommended maximum journey cost:"));
String ShipID, JourneyID; //Variables
int JourneyLength, Crew;
double RateOfPay, CrewCost, TotalCost;
while (input.hasNext()) { //EOF-Controlled While Loop
System.out.println("While Enter"); // For debugging purpose
ShipID = input.nextLine();
JourneyID = input.nextLine();
JourneyLength = input.nextInt();
input.nextLine(); // Enter this to read the data of skipped Line
Crew = input.nextInt();
input.nextLine();
CrewCost = 0; //Default Values Set
TotalCost = 0;
for (int x = Crew; x > 0; x--) { //For Loop updates the above values
System.out.println("While Under if Enter");// For debugging purpose
RateOfPay = input.nextDouble();
input.nextLine();
CrewCost = RateOfPay * JourneyLength;
TotalCost = TotalCost + CrewCost;
System.out.println("While Under if Exit");// For debugging purpose
}
if (TotalCost < RecommendedMaximum) { //if-else statements to compare values
output.println("The total cost of...");
} else if (TotalCost == RecommendedMaximum) {
System.out.println("The total cost of...");
output.println("The total cost of...");
} else {
System.out.println("The total cost of...");
}
System.out.println("While Exit"); // For debugging purpose
}
output.close(); //Close both Scanner and Printwriter
input.close();
}
}

"exception in thread main java.lang.arrayindexoutofboundsexception" when using an array + for loop

when I wrote this code to prompt the user for how many numbers are going to be entered, I got an error saying: "exception in thread main java.lang.arrayindexoutofboundsexception"
PS: note that I used an array of int + for loop to write it.
import java.util.*;
public class Pr8{
public static void main(String[] args){
Scanner scan = new Scanner (System.in);
//Prompt the user for how many numbers are going to be entered.
System.out.print("*Please write how many numbers are going to be entered: ");
int a = scan.nextInt();
int[] n = new int[a];
for (int i = 0; i < a; i++){
System.out.print("*Please enter an enteger: ");
n[a] = scan.nextInt();
}//for
}//main
}//Pr8
Change
n[a] = scan.nextInt();
to
n[i] = scan.nextInt();
a is not a valid index in an array that only has a elements. The valid indices are 0 to a-1.

calling functions gives "NoSuchElementException"

I'm whipping together a simple Java program to explain loops. I want each demonstration in a separate function. Right now, each function works fine, but only when the other isn't called. If I call both I get the following errors at run-time:
Please input a positive integer as the end value: 5
The summation is: 9
How many rows do you want your triangle to be?: Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at loops.exercise2(loops.java:48)
at loops.main(loops.java:11)
Code:
import java.util.Scanner;
public class loops
{
public static void main( String args[] )
{
exercise1();
System.out.println();
exercise2();
}
public static void exercise1()
{
int limit;
int i;
int sum;
Scanner keyboard = new Scanner(System.in);
System.out.print ("Please input a positive integer as the end value: ");
limit = keyboard.nextInt();
i=1;
sum = 0;
while (i <= limit)
{
sum = sum + i;
i = i + 2;
}
System.out.print("The summation is: " + sum);
keyboard.close();
}
public static void exercise2()
{
int numRows, i, j;
Scanner keyboard = new Scanner(System.in);
System.out.print("How many rows do you want your triangle to be?: ");
numRows = keyboard.nextInt();
for(i=0; i<numRows; i++)
{
for(j=0; j<=i; j++)
{
System.out.print("*");
}
System.out.println();
}
keyboard.close();
}
}
This is happening because when you close your Scanner, it also closes the input stream, which in this case is System.in. When you try to instantiate the Scanner in your execise2 method, the input stream is closed.
See this SO post...
https://stackoverflow.com/a/13042296/1246574
My guess is your Scanner classes are interfering with each other. exercise1 takes input from standard in then closes when it's done. Then exercise2 also tries to get input from standard in which is closed.
I would suggest you only make 1 Scanner and pass it as a parameter to both exercise1 and exercise2 and then close it after both calls.
Make a global scanner, and initiate it only once, then call its methods.
Try not calling keyboard.close();

Categories