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.
Related
I'm trying to write a class that will take in numbers from a file, but I keep running into this error when I run:
Java.util.NoSuchElementException: Null(in java.util.Scanner)
This is my code:
import java.util.*;
import java.io.*;
public class finalMain
{
public static void main (String args[]) throws IOException
{
int lineNumber = 0;
Scanner sc = new Scanner (new File ("Prog349f.txt"));
System.out.println("Student Quiz 1 Quiz2 MidTerm Final Final % Grade");
while(sc.hasNextLine())
{
lineNumber++;
sc.nextLine();
}
for(int i = 1; i <= 1; i++)
{
int quizOne = sc.nextInt();
int quizTwo = sc.nextInt();
int midterm = sc.nextInt();
int finalTest = sc.nextInt();
finalGrade studentNext = new finalGrade(sc.nextInt(),sc.nextInt(), sc.nextInt(),sc.nextInt(), i);
System.out.println(studentNext);
}
sc.close();
}
}
I'm thinking maybe I need to create two scanner objects, one for each line or something but I don't know how I would go about doing that.
You have misunderstood the usage of Scanner methods : sc.nextLine(); consumes and returns the line.
That means that you're currently reading the whole file with sc.nextLine();, discarding the result, and only then you try to read 4 ints, that can't be read since the Scanner is at the end of the file.
You should instead use one of these two methods :
If you're positive that each line of your file contains 4 ints separated by space (or any other specific character), and nothing more, you can then scan 4 ints while the scanner has a next line.
If there might be variations, or useless data, you should keep your hasNextLine() and nextLine() calls as they are, then use regex, split+indexing or another Scanner to retrieve the 4 ints from the line.
I'm trying to make a "for" loop in which it asks the user to input 10 numbers and then only print the positives.
Having trouble controlling the amount of inputs. I keep getting infinite inputs until I add a negative number.
import java.util.Scanner;
public class ej1 {
public static void main(String args[]) {
int x;
for (x = 1; x >= 0; ) {
Scanner input = new Scanner(System.in);
System.out.print("Type a number: ");
x = input.nextInt();
}
}
}
From a syntax point of view, you've got several problems with this code.
The statement for (x = 1; x >= 0; ) will always loop, since x will always be larger than 0, specifically because you're not introducing any kind of condition in which you decrement x.
You're redeclaring the scanner over and over again. You should only declare it once, outside of the loop. You can reuse it as many times as you need.
You're going to want to use nextLine() after nextInt() to avoid some weird issues with the scanner.
Alternatively, you could use nextLine() and parse the line with Integer.parseInt.
That said, there are several ways to control this. Using a for loop is one approach, but things get finicky if you want to be sure that you only ever print out ten positive numbers, regardless of how many negative numbers are entered. With that, I propose using a while loop instead:
int i = 0;
Scanner scanner = new Scanner(System.in);
while(i < 10) {
System.out.print("Enter a value: ");
int value = scanner.nextInt();
scanner.nextLine();
if (value > 0) {
System.out.println("\nPositive value: " + value);
i++;
}
}
If you need to only enter in ten values, then move the increment statement outside of the if statement.
i++;
if (value > 0) {
System.out.println("\nPositive value: " + value);
}
As a hint: if you wanted to store the positive values for later reference, then you would have to use some sort of data structure to hold them in - like an array.
int[] positiveValues = new int[10];
You'd only ever add values to this particular array if the value read in was positive, and you could print them at the end all at once:
// at the top, import java.util.Arrays
System.out.println(Arrays.toString(positiveValues));
...or with a loop:
for(int i = 0; i < positiveValues.length; i++) {
System.out.println(positiveValues[i]);
}
Scanner scan = new Scanner(System.in);
int input=-1;
for(int i=0;i<10;i++)
{
input = sc.nextInt();
if(input>0)
System.out.println(input);
}
I tried using following code for reading int input
import java.util.*;
public Add{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
ArrayList<Integer> arr = new ArrayList<>();
while(scan.hasNextInt()){
arr.add(scan.nextInt());
}
System.out.println(arr);
}
}
When I run the program with any input say -
1 2 4
It does not stop till I press CTRL+c. I have also tried some other variations(for example tried to read it as array of String but that also did not work) but they are the same.Problem is that I don't want to give the size of the input in advance. How can I parse int from console input?
You will need to check for certain input and break from the loop as hasNextInt will wait for input from keyboard. You could solve it by following:
int number;
while(scan.hasNextInt()){
number = scan.nextInt();
if (number == -1) {//if user types in -1, then you will come out of the loop.
break;
}
arr.add(number);
}
Since you are using scanner, you may try the following trick instead of using the ArrayList -
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number: ");
while (sc.hasNextInt()) {
int num = sc.nextInt();
System.out.println("Your entered number is: " + num);
}
If you use hasNextInt() then you don't have to think about the parsing of number. A token that is not a integer will break out you from the loop.
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();
}
}
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();