Why gets my code after end of file statement ignored? - java

I'm currently trying an example from my textbook on learning java, but my code after an EoF statement just gets ignored by the compiler.
package lettergrades;
import java.util.Scanner;
public class LetterGrades {
public static void main(String[] args) {
int total = 0;
int gradeCounter = 0;
int aCount = 0;
int bCount = 0;
int cCount = 0;
int dCount = 0;
int fCount = 0;
Scanner input = new Scanner(System.in);
System.out.printf("%s%n%s%n %s%n %s%n", "Enter the integer grades in the range 0-100", "Type the end-of-file indicator to terminate input", "on unix type <ctrl> d then press Enter","On windows type <Ctrl> z then press enter");
while (input.hasNext()){
int grade = input.nextInt();
total += grade;
++gradeCounter;
switch (grade/10){
case 9:
case 10:
++aCount;
break;
case 8:
++bCount;
break;
case 7:
++cCount;
break;
case 6:
++dCount;
break;
default:
++fCount;
break;
}
}
System.out.printf("%nGrade Report:%n");
if (gradeCounter !=0){
double average = (double) total/gradeCounter;
System.out.printf("total of the %d grades entered is %d%n", gradeCounter, total);
System.out.printf("Class average is %.2f%n", average);
System.out.printf("%n%s%n%s%d%n%s%d%n%s%d%n%s%d%n%s%d%n", "Number of students that received each grade","A: ", aCount, "B: ", bCount , "C: ", cCount, "D: ", dCount, "F: ", fCount);
}
else
System.out.println("No grades were entered");
}
}
This is the output i get :
Enter the integer grades in the range 0-100
Type the end-of-file indicator to terminate input
on unix type <ctrl> d then press Enter
On windows type <Ctrl> z then press enter
But when i input ctrl D and press enter, nothing happens. Why don't the printf and if statements work?

As e.g. #FredLarson is reporting, it's working fine for most. You're relying on EOF character resulting in sysin being closed, which will in turn cause scanner's hasNext() to return false.
Evidently, on your system, that isn't working. If you're running this inside an IDE's 'console', they often don't let you close sysin or work differently from the command line.
You can try to figure out which voodoo key combo ends things, but there is an alternative.
Instead of EOF, or in addition to EOF, make another symbol that ends inputs. Perhaps 0, or 'END'. In the later case you can no longer rely on nextInt, you'd have to call next, check if it is END, if yes, stop accepting input, and if not, toss it through Integer.parseInt to end up with a numeric value.
Now you no longer have to mention various platforms in your console messages, and you avoid these issues.

Related

GPA calculator assistance

Hi I was wondering if I could get some help with a GPA calculator.
What it needs to do is:
The input will consist of a sequence of terms, e.g., semesters.
The input for each term will consist of grades and credits for courses taken within that term.
For each term, the user will type in an integer that represents the number of courses
taken within that term.
Each course is specified by a String letter grade and an int number of credits, in that order, separated by white space. 5. If the user types in -1 for the number of courses taken in a term, then the program must print a final overall summary and then terminate.
DO NOT prompt for any input. Thus, after you run your program in BlueJ, type Ctrl-T to force the Terminal window to pop up.
As always, follow the input / output format depicted in the Sample runs section.
Shown below is the error message I get and the code I have, thank you for any assistance in advance or tips I could try.
Terminal window and error message:
import java.util.Scanner;
/*
*
*
*/
public class Prog2 {
public static void main(String args[]) {
Scanner numberInput = new Scanner(System.in);
int numberofClasses = numberInput.nextInt();
Scanner input = new Scanner(System.in);
String [] grade = new String[5];
int [] credit = new int [5];
double totalCredit = 0.0;
double realGrade = 0.0;
double result = 0.0;
while (numberofClasses > 0)
{
for (int x = 0; x < numberofClasses; x++ )
{
grade[x] = input.next();
credit[x] = input.nextInt();
}
for(int x=0;x < numberofClasses; x++ ){
if(grade[x].equals("A+")){
realGrade=4.0;
}
else if(grade[x].equals("A")){
realGrade=4.0;
}
else if(grade[x].equals("A-")){
realGrade=3.67;
}
else if(grade[x].equals("B+")){
realGrade=3.33;
}
else if(grade[x].equals("B")){
realGrade=3.00;
}
else if(grade[x].equals("B-")){
realGrade=2.67;
}
else if(grade[x].equals("C+")){
realGrade=2.33;
}
else if(grade[x].equals("C")){
realGrade=2.00;
}
else if(grade[x].equals("C-")){
realGrade=1.33;
}
result = result+realGrade*credit[x];
totalCredit=totalCredit+credit[x];
}
System.out.println("Summary for term:");
System.out.println("----------------------------------");
System.out.println("Term total grade points: " + result);
System.out.println("Term total credits:" + totalCredit);
System.out.println("GPA:"+result/totalCredit);
}
// This block is getting used later please ignore
System.out.println("Final Summary:");
System.out.println("----------------------------------");
System.out.println(" Overall terms");
System.out.println(" Total grade points: " + result);// this needs to be all );
System.out.println(" Total credits" + totalCredit);//This needs to be all );
System.out.println("Cumulative GPA:"+result/totalCredit);
}
}
When your while loop ends, numberofClasses still contains the value that was entered before the while loop started the first time. Specifically, after you output the line:
GPA=3.0588...
you hit the end of the loop, then return to:
while (numberofClasses > 0)
which is true. The next "3" that you enter doesn't go into numberofClasses, it is picked up by
grade[x] = input.next();
Then the "A" is picked up by
credit[x] = input.nextInt();
which throws an exception since it's not an integer.
All you need to do is ask for the number of classes again at the end of the while loop:
System.out.println("GPA:"+result/totalCredit);
numberofClasses = numberInput.nextInt();
}
Output:
5
A 3
B 2
C 4
A 5
C 3
Summary for term:
----------------------------------
Term total grade points: 52.0
Term total credits:17.0
GPA:3.0588235294117645
3
A 3
B 5
C 1
Summary for term:
----------------------------------
Term total grade points: 81.0
Term total credits:26.0
GPA:3.1153846153846154
i recommend looking into whether your compiler or IDE has a "debug" feature. It is a very helpful tool, and lets you watch how your program goes through your code
Just a tip...
When you ask for input, print what you're asking for first. When I launched your program I had no idea what to do. Try adding System.out.println("input number of classes you took");before you prompt for that number.
Here is what is wrong. (If you printed what you're asking for first, this would be more apparent).
after your program displays the stats, you enter 5. Yet your program is actually still on this line grade[x] = input.next(); on line 22 i believe.
when you enter 5, your scanner is expecting a letter. and an exception is thrown.
you need to consider how you escape this loop here. while (numberofClasses > 0) perhaps use an if statement? otherwise your program loops for forever, never asking for a new class number

Calculator int choice = Integer.parseInt(char_a); java

Trying to create a simple calculator on java. No errors show up in the code. But it still doesn't work at all. am I missing anything?
import java.util.Scanner;
public class JavaApplication15 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("This is a calculator. Enter a letter followed by a number to calculate it.");
System.out.println(" S = sine \n C = Cosine \n T = Tangent \n R = Square Root \n N = natural Log \n X = exit the program");
String num = in.nextLine();
String sValue = num.substring(2);
String char_a = num.substring(0);
int choice = Integer.parseInt(char_a);
double dValue = Double.parseDouble(sValue);
while (choice != 'x'){
switch(choice){
case 's':
Math.sin(dValue);
System.out.println("The sine of your number is " + dValue);
break;
case'c':
Math.cos(dValue);
System.out.println("The Cosine of your number is " + dValue);
break;
case't':
Math.tan(dValue);
System.out.println("The Tangent of your number is " + dValue);
break;
case'r':
Math.sqrt(dValue);
System.out.println("The square root of your number is " + dValue);
break;
case'n':
Math.log(dValue);
System.out.println("The Log of your number is " + dValue);
break;
case'x':
break;
}
}
}
}
I think I see your error.
You're performing operations using the Math class but aren't assigning the result of the operation back to your variable.
For example, Math.cos(dValue); should probably be dValue = Math.cos(dValue);
There are a few problems with your code.
Firstly, you are not using .substring method correctly. It returns everything from the index you specify to the end of your String. So for a user input of "S 4"
sValue equals to "4", but char_a equals to "S 4".
The way you use substring method is:
value = input.substring(2);
operation = input.substring(0,1);
I would actually suggest that you use something like:
params = input.split(" ");
Then you have:
params[0] // as your command
and
params[1] // as your value
This way you don't have to worry about how many symbols each bit actually takes up.
Next, don't convert your command to char like this. My previous suggestion means you should really be using something like
if (params[0].equals("sin")) {
} else if (params[0].equals("cos")) {
} else {
// catch unknown command
}
However, you can convert to char simply by:
sValue.toCharArray()[0]
Also, there is no reason why your switch statement should be in a while loop. There is nothing to be done continuously, it will just keep printing the same answers. And lastly, ajb said, you calculate the values and throw them away, whilst printing the old value. You have to use:
System.out.println("The Tangent of your number is " + Math.tan(dValue));

Switch statements and double values

I am just learning how to use switch statements. I am trying to create a shopping cart of items sold at a grocery store. I have to create a program that adds the values of the items sold and then print the final value. This is what I have so far but when I terminate my program I get an error and it doesn't display the final value.
Any help is much appreciated!!
package Exercises;
import java.util.Scanner;
public class CalculatingSales {
public static void main(String[] args)
{
int total = 0;
int prod1Count = 0, prod2Count = 0, prod3Count = 0, prod4Count = 0, prod5Count = 0;
Scanner input = new Scanner(System.in);
System.out.printf("%s%n%s%n %s%n %s%n %s%n","Enter product number sold: " //prompt user to enter input
,"NOTE: Product number must be between 1 & 5",
"To terminate input... ",
"On UNIX/Linus?mac OS X type <Ctrl> d then press Enter",
"On Windows type <Ctrl> z then press Enter");
while(input.hasNext())
{
int item = input.nextInt();
total =+ item;
double product1;
double product2;
double product3;
double product4;
double product5;
switch (item + total)
{
case 1:
product1 = 2.98;
++prod1Count;
break;
case 2:
product2 = 4.50;
++prod2Count;
break;
case 3:
product3 = 9.98;
++prod3Count;
break;
case 4:
product4 = 4.49;
++prod4Count;
break;
case 5:
product5 = 6.87;
++prod5Count;
break;
default:
System.out.println("ERROR. You did not enter a value between 1 & 5!");
break;
}//end switch
}//end while
double shoppingCart = (double) total;
System.out.printf("%nTotal retail value of all products is: $%d", shoppingCart);
}
}
The problem is here:
System.out.printf("%nTotal retail value of all products is: $%d", shoppingCart);
The printf is expecting an int but you are passing an double as an argument.
Try this:
System.out.printf("%nTotal retail value of all products is: $%.2f", shoppingCart);
Also you should change total =+ item; to total += item;
There are a number of problems with the code. The error at the end is because you are trying to output a double and specifying an integer to print. $%d should be $%f however to make money display to two decimal places you can use $%.2f. More information on formatting can be found in this documentation
The major problems though are in your loop. The switch statement should only be passed the item number you want to compare to and do something accordingly.So the switch simply has to be switch (item) . There is a simpler way to do the total and do the switch. You can keep a running total by adding to it the value of the product the person selected each time through the loop. Upon exiting it should be the total amount for all the items selected. If you enter an item out of range it effectively adds 0.
At the end you really should close the scanner to do proper cleanup so input.close() would be a good idea as well.
The code could look something like:
package Exercises;
import java.util.Scanner;
public class CalculatingSales {
public static void main(String[] args)
{
double total = 0.0;
Scanner input = new Scanner(System.in);
System.out.printf("%s%n%s%n %s%n %s%n %s%n","Enter product number sold: " //prompt user to enter input
,"NOTE: Product number must be between 1 & 5",
"To terminate input... ",
"On UNIX/Linus?mac OS X type <Ctrl> d then press Enter",
"On Windows type <Ctrl> z then press Enter");
while(input.hasNext())
{
double prodvalue = 0.0;
int item = input.nextInt();
switch (item)
{
case 1:
prodvalue = 2.98;
break;
case 2:
prodvalue = 4.50;
break;
case 3:
prodvalue = 9.98;
break;
case 4:
prodvalue = 4.49;
break;
case 5:
prodvalue = 6.87;
break;
default:
System.out.println("ERROR. You did not enter a value between 1 & 5!");
break;
}//end switch
total += prodvalue;
}//end while
double shoppingCart = total;
System.out.printf("%nTotal retail value of all products is: $%.2f", shoppingCart);
input.close();
}
}
There are much better ways of doing this but as time goes on you will probably learn how this program could be simplified. I wanted to keep the code somewhat structured the way you seemed to be handling things.
If you need the counts of each individual item then you will have to modify the code above to add them back in. I realize this solution may have oversimplified what you needed but at a basic level it keeps the overall total right.

java Scanner.hasNext() usage

public static void main(String args[]){
Scanner in = new Scanner(System.in);
String a = in.next();
if (in.hasNext()) {
System.out.println("OK")
} else {
System.out.println("error");
}
}
What I want is:
if the user type in a String with more than one word, print "OK".
if the user type in a String with only one word, print "error".
However, it doesn't work well. When I type a single word as an input, it doesn't print "error" and I don't know why.
Read a line and then check whether there are more than one word.
String a = in.nextLine();
if( a.trim().split("\\s").length> 1 ){
System.out.println("OK");
} else {
System.out.println("error");
}
Your condition resolves true, if you have any kind of new input. Try something like contains(" ") for testing your input to contain spaces. If you want to make sure the input doesn't just contain spaces but also some other characters, use trim() before.
hasNext() is a blocking call. Your program is going to sit around until someone types a letter, and then go to the System.out.println("OK"); line. I would recommend using an InputStreamReader passing in System.in to the constructor, and then reading the input and determining its length from there. Hope it helps.
From Scanner#hasNext() documentation
Returns true if this scanner has another token in its input. This method may block while waiting for input to scan. The scanner does not advance past any input.
So in case of only one word scanner will wait for next input blocking your program.
Consider reading entire line with nextLine() and checking if it contains few words.
You can do it same way you are doing now, but this time create Scanner based on data from line you got from user.
You can also use line.trim().indexOf(" ") == -1 condition to determine if String doesn't contain whitespace in the middle of words.
Scanner#hasNext() is going to return a boolean value indicating whether or not there is more input
and as long as the user has not entered end-of-file indicator, hasNext() is going to return true
The end-of-file indicator is a system-dependent keystroke combination
which the user enters to indicate that there’s no more data to input.
on UNIX/Linux/Mac OS X it's ctrl + d,,, On Windows it's ctrl + z
look at this simple example to see how to use it
// Fig. 5.9: LetterGrades.java
// LetterGrades class uses the switch statement to count letter grades.
import java.util.Scanner;
public class LetterGrades
{
public static void main(String[] args)
{
int total = 0; // sum of grades
int gradeCounter = 0; // number of grades entered
int aCount = 0; // count of A grades
int bCount = 0; // count of B grades
int cCount = 0; // count of C grades
int dCount = 0; // count of D grades
int fCount = 0; // count of F grades
Scanner input = new Scanner(System.in);
System.out.printf("%s%n%s%n %s%n %s%n",
"Enter the integer grades in the range 0–100.",
"Type the end-of-file indicator to terminate input:",
"On UNIX/Linux/Mac OS X type <Ctrl> d then press Enter",
"On Windows type <Ctrl> z then press Enter");
// loop until user enters the end-of-file indicator
while (input.hasNext())
{
int grade = input.nextInt(); // read grade
total += grade; // add grade to total
++gradeCounter; // increment number of grades
// increment appropriate letter-grade counter
switch (grade / 10)
{
case 9: // grade was between 90
case 10: // and 100, inclusive
++aCount;
break; // exits switch
case 8: // grade was between 80 and 89
++bCount;
break; // exits switch
case 7: // grade was between 70 and 79
++cCount;
break; // exits switch
case 6: // grade was between 60 and 69
++dCount;
break; // exits switch
default: // grade was less than 60
++fCount;
break; // optional; exits switch anyway
} // end switch
} // end while
// display grade report
System.out.printf("%nGrade Report:%n");
// if user entered at least one grade...
if (gradeCounter != 0)
{
// calculate average of all grades entered
double average = (double) total / gradeCounter;
// output summary of results
System.out.printf("Total of the %d grades entered is %d%n",
gradeCounter, total);
System.out.printf("Class average is %.2f%n", average);
System.out.printf("%n%s%n%s%d%n%s%d%n%s%d%n%s%d%n%s%d%n",
"Number of students who received each grade:",
"A: ", aCount, // display number of A grades
"B: ", bCount, // display number of B grades
"C: ", cCount, // display number of C grades
"D: ", dCount, // display number of D grades
"F: ", fCount); // display number of F grades
} // end if
else // no grades were entered, so output appropriate message
System.out.println("No grades were entered");
} // end main
} // end class LetterGrades
and the output will be something like this
Enter the integer grades in the range 0–100.
Type the end-of-file indicator to terminate input:
On UNIX/Linux/Mac OS X type <Ctrl> d then press Enter
On Windows type <Ctrl> z then press Enter
99
92
45
57
63
71
76
85
90
100
^Z
Grade Report:
Total of the 10 grades entered is 778
Class average is 77.80
Number of students who received each grade:
A: 4
B: 1
C: 2
D: 1
F: 2
Resources Learning Path: Professional Java Developer
and Java™ How To Program (Early Objects), Tenth Edition

Trouble trying to restart my Java program

After looking up numerous ways to restart a Java program within itself, a while loop seemed like the easiest option. Here's an example of a basic calculator program I'm trying this with:
import java.util.Scanner;
class a {
public static void main(String args[]){
boolean done = false;
int oper;
Scanner input = new Scanner(System.in);
System.out.println("McMackins Calc v2.0 (Now with fewer crashes!)");
while (!done)
{
System.out.println("What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
oper = input.nextInt();
switch (oper){
case 0:
done = true;
break;
case 1:
add addObject = new add();
addObject.getSum();
break;
case 2:
sub subObject = new sub();
subObject.getDifference();
break;
case 3:
times multObject = new times();
multObject.getProduct();
break;
case 4:
divide divObject = new divide();
divObject.getQuotient();
break;
case 5:
remain remObject = new remain();
remObject.getRemainder();
break;
case 6:
avg avgObject = new avg();
avgObject.getAvg();
break;
case 7:
interest intObject = new interest();
intObject.getInterest();
break;
default:
System.out.println("Invalid entry.");
break;
}
}
input.close();
}
}
However, this seems to throw out a NoSuchElementException at the end of the first time through the loop, and crashes the program. The function of this class is to take the initial input from the user to determine which class to use, which will determine which mathematical operation to perform. Everything works fine without the while (!done) loop.
Example usage:
McMackins Calc v2.0 (Now with fewer crashes!)
What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):
1
How many addends?
1
Enter your numbers now.
1
You have entered 1 addend.
The sum is: 1.0
What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):
Enter a valid integer.
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at a.main(a.java:13)
I've also tried just having the other classes refer back to this one, but since main is a static method, I cannot access it the way I intended.
Note that I'm a bit of a beginner at Java, which is why my program is pretty simple, so try to keep it simple if it can be, or post code and then in DETAIL explain what it means so I can not only fix this problem, but future ones as well.
Thank you!
EDIT:
The code is formatted better within my editor. The braces came out in odd positions when I posted it here.
Since apparently a is written correctly, this is my add class. Hopefully this will clear something up.
import java.util.Scanner;
public class add {
public void getSum(){
Scanner input = new Scanner(System.in);
double total, addend;
int entries, count;
total = 0;
count = 0;
System.out.println("How many addends?");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
entries = input.nextInt();
System.out.println("Enter your numbers now.");
while (count < entries){
while (!input.hasNextDouble()){
System.out.println("Enter a valid number.");
input.next();
}
addend = input.nextDouble();
total = total + addend;
count++;
if (count == 1){
System.out.println("You have entered " + count + " addend.");
}else if (count > entries){
System.out.println("You have entered too many addends! Contact program developer.");
}else{
System.out.println("You have entered " + count + " addends.");
}
}
System.out.println("The sum is: " + total);
input.close();
}
}
public static void main(String args[]){
boolean done = false;
int oper;
Scanner input = new Scanner(System.in);
System.out.println("McMackins Calc v2.0 (Now with fewer crashes!)");
while (!done) {
System.out.println("What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
oper = input.nextInt();
switch (oper){
case 0:
done = true;
break;
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
case 3:
System.out.println("3");
break;
case 4:
System.out.println("4");
break;
case 5:
System.out.println("5");
break;
case 6:
System.out.println("6");
break;
case 7:
System.out.println("7");
break;
default:
System.out.println("Invalid entry.");
break;
}
}
input.close();
}
This seemed to work for me so perhaps the error is something to do with your own classes (add, divide) etc.
Also, it's best to keep with convention when creating your own classes by capitalizing the first letter e.g. "add" should be "Add".
You could probably make this a little bit easier to read by building a general "Operations" class which holds an add method, a subtract method etc.
EDIT:
try this for your add method:
public static int add() {
Scanner s = new Scanner(System.in);
int counter = 0;
System.out.println("How many numbers to add?");
int numCount = s.nextInt();
for(int i = 0; i < numCount; i++) {
System.out.println("enter number");
counter += s.nextInt();
}
return counter;
}
Use bufferedreader and inputstream instead of Scanner class. This class creates a lot of bugs and errors, since sometimes it takes more arguments, that you expect it to take.
Also:
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
Your using hasNextInt method wrong, instead of it try to make simple while loop with Boolean and input.next() should be replaced with input.nextLine().
Another thing, you should check,if user typed integer instead of string or something in the while loop and it range. If everything is okay, you should change Boolean value to true and make him go out of the while loop.
For future users who are wondering how to fix this issue, through some reprogramming, I discovered that my problem was closing the input variable BEFORE the end of the loop. By having the program restart indefinitely and only close input when done, this program works fine.
Thanks to Benjamin's response, I am currently in the process of cleaning up and shortening my code by way of for loops.

Categories