Unable to break out of For Loop in Java - java

I am a beginner and was making a small program to practice what i have learnt.
I was writing code to check the grade of a student.
This is the code :
import java.util.*;
public class Grader {
public static void main(String[] args) {
String studentName;
int rollNo = 0;
Scanner inputter = new Scanner(System.in);
System.out.println("Please enter the roll number of the student: ");
rollNo = inputter.nextInt();
System.out.println("Thank you. Now, please enter the student's name: " );
studentName = inputter.next();
for(int i=0; ; i++){
System.out.println("Please enter a valid examination type, i.e FA or SA: ");
String examType = inputter.next();
examType = examType.toUpperCase();
if(examType == "FA" || examType == "SA"){
break;
}
}
}
}
The problem I am facing is that even though I enter a valid examType, the For loop doesn't break.

You need to use String.equals().
Scanner.next() returns a String. Using == on a string doesn't give any errors but will test reference equality instead of value equality. It won't return true even if the strings are equal in value.
Correct code:
if(examType.equals("FA") || examType.equals("SA")){
break;
}
EDIT
OP mentioned in a comment that the loop is to run without ending until hitting break. You can create an infinite loop in either of these two ways:
for(;;){
//runs infinitely
}
OR
while(true){
//runs infinitely
}
Both of these infinite loops are broken with break. Also, you use less memory (albeit a small and almost insignificant difference) because you don't have a counter variable. In the next-to-impossible case that the user enters invalid input so many times that the integer overflows, not having a variable eliminates this risk. You also save processor time because there isn't an instruction to allocate memory or add one to the number.

public static void main(String args[]) {
String studentName;
int rollNo = 0;
Scanner inputter = new Scanner(System.in);
System.out.println("Please enter the roll number of the student: ");
rollNo = inputter.nextInt();
System.out.println("Thank you. Now, please enter the student's name: " );
studentName = inputter.next();
for(int i=0; ; i++){
System.out.println("Please enter a valid examination type, i.e FA or SA: ");
String examType = inputter.next();
examType = examType.toUpperCase();
if(examType.equals("FA") || examType.equals("SA")){
break;
}
}
}
This is working fine.

You haven't set a limit, for example
for(int i = 0; i < somevalue; i++)
otherwise a while loop might be a better choice like:
while(examType.equals("FA") || examType.equals("SA")

For best coding practice the usage of equals operation for Strings like below code snippet as per Sonar compliance standard.
("SA".equals (examType))

Related

do while loop with a Yes/No user prompt

Im having issues with my code. The code is to find a factorial of a number, then ask if you want to run the program again, its suppose to run again then exit. However, when I enter Y to restart the program it breaks and wont restart and when I enter N to exit it wont exit the program.
private static Object Cont;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Greetings
System.out.println("Welcome to my factorial program! ");
System.out.println("Please choose from the following: ");
//Menu
System.out.println("1. Run Program");
System.out.println("2. Exit Program");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("This program will determine the factorial value of positive integers.");
do {
System.out.println("The starting number is 1.");
System.out.println("Please enter an ending integer value:");
int n = scanner.nextInt();
for (int i = 1; i <= n; i++) {
System.out.println(i + "! = " + fact(i));//call to function
}
System.out.println("Run factorial program again? (Y for Yes, N for No): ");
String Cont = scanner.next();
if (Cont.equals("N")) {
break;
}
} while (Cont.equals("Y"));// do while loop
break;
//Menu Exit
case 2:
System.out.println("Thank you for using the program.");
System.out.println("Goodbye");
default:
System.exit(1); // remebered from last week to set this to one
System.out.println("Goodbye");
break;
}
}//Factorial Math
static long fact(int x) {
long f = 1;
for (int i = 1; i <= x; i++) {
f = f * i;
}
return f;
} //End Main Method
What am I missing or doing wrong?
You have a couple of problems here.
The first problem is that you have declared two distinct Cont variables. The first one is a static field. The second one is a local variable that is declared in the body of the loop.
I don't know why you declared the static field, but I imagine you did it because the } while (Cont.equals("Y")); didn't compile without it. (That is because the Cont variable declared in the loop is not in scope outside of the loop's body.) Unfortunately, it was not the correct solution. Because, you now have code that is assigning to one variable and tests a different one. Naturally, that doesn't work.
To my mind, the correct solution is to get rid of the static field, and the declaration in the loop body. Than add a declaration for Cont before the start of the loop. (It shouldn't have an initialization). Finally, in the loop you just need to read (using the scanner) and assign a string to Cont so that you can test in the loop condition.
The second problem is that you have a redundant test in there. If you are going to test to see if you need to continue using } while (Cont.equals("Y")); you don't also need to test if Cont is "N" and break.
Relatedly, equals("Y") is not the same as not equals("N"). (Consider "Hello" ... or "n". They are neither "Y" or "N".) So if you really want to stop the loop when the user types N, then the loop termination condition should be:
} while (!Cont.equals("N")); // keep looping while not 'N'
Finally there are a couple of significant style-related issues.
Declaring a static field is usually a mistake.
It is a mistake to use a field when you should be using a local variable. State that is only relevant to a single execution of a method should be1 represented using a local variable.
It is a major stylistic error for a variable to start with an uppercase letter. Cont should be cont.
If you ever work in a professional Java development team that pays attention to style, you will get a hard time for ignoring Java identifiers conventions. And (IMO) your teacher should dock style marks for this mistake.
1 - Reasons: 1) It makes the method harder to read because the variable declaration is further away from its use. 2) It typically makes the code non-reentrant. 3) It opens you up to unwanted coupling between methods; e.g. if two methods accidentally share the same "local variable declared as a field". 4) In many cases it uses more memory.
You need an additional break and declare Cont before the do loop:
//private static Object Cont; This is is not declared on the right location, we'll declare it later
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Greetings
System.out.println("Welcome to my factorial program! ");
System.out.println("Please choose from the following: ");
//Menu
System.out.println("1. Run Program");
System.out.println("2. Exit Program");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("This program will determine the factorial value of positive integers.");
String Cont = null; // Cont must be declared here
do {
System.out.println("The starting number is 1.");
System.out.println("Please enter an ending integer value:");
int n = scanner.nextInt();
for (int i = 1; i <= n; i++) {
System.out.println(i + "! = " + fact(i));//call to function
}
System.out.println("Run factorial program again? (Y for Yes, N for No): ");
Cont = scanner.next();
if (Cont.equals("N")) {
break;
}
} while (Cont.equals("Y"));// do while loop
break;
//Menu Exit
case 2:
System.out.println("Thank you for using the program.");
System.out.println("Goodbye");
break; // requires this additional break
default:
System.exit(1); // remembered from last week to set this to one
System.out.println("Goodbye");
break;
}
}//Factorial Math
static long fact(int x) {
long f = 1;
for (int i = 1; i <= x; i++) {
f = f * i;
}
return f;
} //End Main Method

Writing a WHILE loop in Java to compute the largest value in a sequence that prevents no user input

I'm trying to learn (self-taught) Java by reading Big Java, Late Objects from by Cay Horstmann. I'm using repl.it to write my code (if you may want to look it up, it's public)
A selfcheck question of Chapter 4 Loops is:
How can you overcome the problem of when the user doesn't provide any input in the algorithm of section 4.7.5 (titled Maximum and Minimum) and the WHILE loop just terminates the program for this reason ?
They basically ask to rewrite the code so it solves this problem.
The information of section 4.7.5 you need to solve this problem: To compute the largest value in a sequence, keep a variable that stores the largest element that you have encountered, and update it when you find a larger one.
(This algorithm requires that there is at least one input.)
double largest = in.nextDouble();
while (in.hasNextDouble())
{
double input = in.nextDouble();
if (input > largest)
{
largest = input;
}
}
This is what the book suggests as the answer to this problem (but I disagree):
One solution is to do all input in the loop and introduce a Boolean variable that checks whether the loop is entered for the first time.
double input = 0;
boolean first = true;
while (in.hasNextDouble())
{
double previous = input;
input = in.nextDouble();
if (first) { first = false; }
else if (input == previous) { System.out.println("Duplicate input"); }
}
I don't fully understand the first sentence. And I disagree this as a solution for the problem because (as far as I can tell) it tests whether the input has been entered before, instead of testing if any sort of user input has been provided..
I tried to merge those two sections of code together but I can't seem to make it work. Or more specific: figure out how to build it. What variables / loops do I need? In which order do I write this?
I've made a flowchart in Visio of the first section of code but have no clue how to continue.
This is what I've written so far:
import java.util.Scanner;
class Main {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter the number: ");
double largest = 0;
while (input.hasNextDouble())
{
double value = input.nextDouble();
if (value > largest)
{
largest = value;
System.out.println("The largest input till now is: " + largest);
}
}
Can someone:
Ask me questions which help me to solve this question? I.e. Tell me what tools I need (WHILE, FOR etc.)
Provide a solution in text which I can hopefully transform in code
Or write the code for me (I haven't learned arrays yet, so please solve it without)
Thanks in advance,
So I worked on this for a bit and I think I have something close to what you're looking for using a do while loop.
This code accepts user input first, then checks it's value in comparison to the last input and return either "Input a higher value", "Duplicate number found", or it sets the last number entered to the current number.
I hope this helps you get your code to where you'd like it to be! I'm still new, so I apologize if this is not entirely optimized.
Also, I have not added a way to exit the loop, so you may want to add a check on each iteration to see if the user would like to continue.
public static void main(String[] args) {
double userInput = 0;
double prevNum = 0;
boolean hasValue = false;
boolean exitCode = false;
do {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter a number: ");
userInput = sc.nextDouble();
do {
if (userInput<prevNum) {
System.out.println("Please enter a number higher than " + prevNum);
hasValue=true;
}
else if (userInput==prevNum) {
System.out.println("Duplicate input detected.");
hasValue=true;
}
else {
prevNum = userInput;
hasValue = true;
}
}
while(hasValue==false);
System.out.println(prevNum);
System.out.println(userInput);
}
while(exitCode==false);
}
If you want compute if the number entered is the largest entered from the beginning but declare it at the largest if it's the first iteration then do this :
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean flag = true;
double largest = 0;
System.out.println("Enter the number: ");
while (input.hasNextDouble()){
double value = input.nextDouble();
if (flag) {
flag = false;
largest = value;
}
else if (value > largest) largest = value;
System.out.println("The largest input till now is: " + largest);
System.out.println("Enter a new number: ");
}
}

Confusion on do-while loop

Here is my Code
import java.util.*;
public class dowhile
{
public static void main (String [] args)
{
Scanner kb = new Scanner (System.in);
System.out.println("Enter number of # to be displayed: ");
int tim = kb.nextInt();
String hash = "#";
do
{
System.out.println(hash);
hash = hash + 1;
} while (hash.equals(5));
}
}
I am confused on how to display number of # after asked by the user..
I know hash.equals(5) does not make sense.
how can i fix this code?
Any one please give the suggestion to me.
You could use tim as a counter, and decrement it before testing if it's greater than 0. Something like,
int tim = kb.nextInt();
do {
System.out.print("#");
} while (--tim > 0);
System.out.println();
You can also use Apache commons-lang3 which has StringUtils.repeat(String, int)
Parameters:
str - the String to repeat, may be null
repeat - number of times to repeat str, negative treated as zero
hash is the string that you are going to print, so you should never change its value like this:
hash = hash + 1; // this does not actually compile anyway.
To keep track of how many times you still need to print, you need an int variable. As you can see, tim is an int and it already has the user input stored in it. Let's use tim as our counter.
Each time you print a # you decrease tim by 1. And in the loop condition, you write tim > 0. This will make the loop run as long as tim is greater than 0.
Scanner kb = new Scanner(System.in);
System.out.println("Enter number of # to be displayed: ");
int tim = kb.nextInt();
String hash = "#";
do {
System.out.println(hash);
tim--; // this is equivalent to tim = tim - 1;, in case you did not know
} while (tim > 0);
However, I don't think using a do-while loop is suitable here. What if the user entered 0? One # will still be printed. That's no good isn't it?
I suggest a for loop here:
Scanner kb = new Scanner(System.in);
System.out.println("Enter number of # to be displayed: ");
int tim = kb.nextInt();
String hash = "#";
for (int i = 0 ; i < tim ; i++) {
System.out.println(hash);
}
Declare one int variable before the loop. Increment number by one in do and check then number in while loop is will print your desired output.
int i=0;
do
{
System.out.println(hash);
i=i + 1;
} while (i<tim);

Trying to setup break statement

I have this java code I created for a course. I have tried and continue to fail implement a break statement.
Can someone point me in the right direction?
import java.util.Scanner;
public class gradeAverage {
public static void main( String[] args ){
Scanner input = new Scanner(System.in);
int input1;
int input2;
int input3;
//Calculate
int studentAvg;
//Prompt for first user input or break if input = q
System.out.print( "Enter first student grade or q to quit: ");
if {
(input1=input.nextInt() = q)
break;
else
input1=input.nextInt() =;
}
//Prompt for second user input or break if input = q
System.out.print( "Enter second student grade or q to quit: ");
input2=input.nextInt();
//Prompt for third user input or break if input = q
System.out.print( "Enter third student grade or q to quit: ");
input3=input.nextInt();
studentAvg=(input1+input2+input3)/3;
System.out.printf( "The Student's grade average is %d\n" , studentAvg);
}
}
A break statement needs to be inside a loop or some sort (for, while, or do), you cannot break out of an if conditional.
If you put your code inside this:
while(true) {
...
}
Then your break would work fine.
Also the format of an if statement is:
if (condition) {
...
} else {
}
You seem to have a if { (condition) in your code...
Oh and = is an assignment of a value to a variable, == is an equality check, you have them mixed up.
First of all your syntax of If statement is totally wrong . That needs to be corrected.
Second this is that , Break statement is used to break a loop in between. So it should be used like
while{
................
Break;
................
}
or
For(.........){
Break;
........
}
//Assuming input is a scanner object.
System.out.print( "Enter first student grade or q to quit: ");
if ((input1=input.nextline()).equalsIgnoreCase("q")) //do you want to use == or =?
break;
else{
//do something
}
This should do the trick for you. Cheers.

I need of assistance with array assigning user inputs to an array, and do-while loop repeat

I'm having a few problems with my code, this is the over all goal of the program.
One of your professors hears of your emerging programming expertise and asks you to write a SINGLE program that can be used to help them with their grading. The professor gives three 50-point exams and a single 100-point final exam. Your program will prompt the user for the student’s name, entered as Firstname Lastname (i.e. Bob Smith), the student’s 3-exam scores and 1-final exam score (all whole numbers). Class size varies from semester to semester, but 100 is the limit (declare as a constant).
Read in information for ALL students before doing any calculations or displaying any output. Verify that the 3 exam scores are between 0-50 points and that the final is between 0-100 as they are entered. Declared minimums and maximums as constant so that they can easily be updated, as needed. If invalid, display an error message and allow the user to re-enter that invalid score. Once all student info is read in, display each student’s name in the format LASTNAME, FIRSTNAME (all uppercase), the student’s exam percentage (total of all exams plus final / total possible) to 1 decimal and the student’s final grade.
This is what I have:
import java.util.*;
import java.text.*;
public class Proj4 {
public static void main(String[] args){
Scanner s= new Scanner(System.in);
String input;
String again = "y";
final int MAX_STUDENTS = 100;
final int MIN_EXAM = 0;
final int MAX_EXAM = 50;
final int MIN_FINAL = 0;
final int MAX_FINAL = 100;
String[] names = new String[MAX_STUDENTS];
int [] exams = new int[MAX_STUDENTS * 4];
int student = 1;
do
{
System.out.print("PLease enter the name of student " + student + ": " );
for (int k = 0; k < 1; k++) {
names[k] = s.nextLine().toUpperCase();
}
for ( int i = 0; i < 4; i++){
if(i==3){
System.out.print("Please enter score for Final Exam: ");
exams[i] = s.nextInt();
}
else{
System.out.print("Please enter score for Exam " + (i+1) + ": ");
exams[i] = s.nextInt();
if((exams[0]<MIN_EXAM||exams[0]>MAX_EXAM)||(exams[1]<MIN_EXAM||exams[1]>MAX_EXAM)||(exams[2]<MIN_EXAM||exams[2]>MAX_EXAM)){
System.out.println("Invalid enter 0-50 only...");
System.out.print("Please re-enter score: ");
exams[i] = s.nextInt();
}
else if(exams[3]<MIN_FINAL||exams[3]>MAX_FINAL){
System.out.println("Invalid enter 0-100 only...");
System.out.print("Please re-enter score: ");
exams[i] = s.nextInt();
}
}
}
System.out.print("do you wish to enter another? (y or n) ");
again = s.next();
if(again!="y")
student++;
}while (again.equalsIgnoreCase ("y"));
System.out.println("***Class Results***");
System.out.println(names[1] + "," + names[0] + " " + "Exam Percentage: "+ ((exams[0]+exams[1]+exams[2]+exams[3])/(MAX_EXAM*3+MAX_FINAL)));
}
}
The problems i have have are:
figuring out how to assign the user entered test scores beyond just the first student, i believe i have it set up correct for just one, but it runs into a problem when i would move on to the second student.
For some reason that I cannot figure out the line
System.out.print("do you wish to enter another? (y or n) ");
again = s.next();
doesn't allow me to enter anything, not y not n not anything, so my program effectively ends there, it doesn't make sense to me because I've done it exactly like that before and it has worked.
other than that, if there are any other problems that you can see with my code pointing them out would be extremely helpful.
Thank you
EDIT-
new problem i am having, after changing to
if(!again.equalsIgnoreCase("y"))
student++;
}while (again.equalsIgnoreCase ("y"));
it lets me type things in now, but after i type in y it prints the next line as
Please enter the name of student 1: Please enter score for Exam 1:
I don't know why or what i need to change to fix it, any suggestions?
`if(again!="y")` is the culprit here
You should use equals() method to check string equality.
if(!again.equals("y"))
If you compare Strings in Java using the == or != operators then you are not actually comparing the values. Instead you are testing if the two Strings are the same Object.
This post explains String comparison well.
To do what you want, change if (again != "y") to if(! (again.equalsIgnoreCase("y")) )
EDIT
I believe your new problem stems from the first for loop you do inside your do loop. Each time you type "y" at the end of your do/while you are going to execute the entire
for (int k = 0; k < 1; k++) {
loop again. This is why after you type "y" you are seeing Please enter the name of student 1: Please enter score for Exam 1:
A "solution" to your new issue would be to make it so the outer for enclosed the inner one, looping through 4 exams for each student usually referred to as a "double for" or "nested for loop".
That said you would then be presented with the issue of having all the exams for ALL students in a single array.
I think now is the time to sit down and put some serious thought into the design of your program. It would be much easier for you if you used a Student object to represent a student and hold their exam scores, IMO. Then you could create an array of Students as opposed to two different arrays you have now.
Here are some "starter" steps (Not necessarily a complete list):
Make a Student class that has variables for the student's first & last name, as well as an array to hold that Students exam scores
In your main class create an ArrayList to hold all of the new Student objects you will be creating.
Do your do/while loop. At the beginning of the loop create a new Student object. Then ask for the Students name and exam scores (note that if you KNOW there will only be the 4 exam scores you don't have to do any extra logic there. You can simply ask for the 4 exam scores using a for loop, or if you want all at one time. if there are a variable number of scores you will have to do some sort of check)
Add the new Student you have created to the ArrayList of Students.
Once the person selects "n", loop through the ArrayList and print the information for each Student!
Your for (int k = 0; k < 1; k++) loop will execute only once (for one student) because you have it set up to execute only while k < 1, which will happen only once. As soon, as you increase k to 1, the loop will stop. I would change it to for (int k = 0; k < MAX_STUDENTS; k++) to make sure it will loop through until you reach the max number of students allowed.

Categories