Java Variable will not initialize in an if statement? - java

I have initialized and declared the variable "average." I do not understand why it won't compile. Does it have to do with the fact that it's in an if else? I've already tried
"|| null" and that is not taking either. What to do?
// declare variables
Scanner keyboard = new Scanner (System.in);
String given;
String middle;
String sur;
String truefalse;
boolean bool;
int exam1;
int exam2;
int exam3;
double average;
// get input
System.out.println("*************** Grade Computer *************");
System.out.println("Enter the student's first name: ");
given = keyboard.nextLine();
System.out.println( "Enter the student's middle initial: ");
middle = keyboard.nextLine();
System.out.println( "Enter the student's last name: ");
sur = keyboard.nextLine();
System.out.println( "Enter EXAM 1 Grade: ");
exam1 = keyboard.nextInt();
System.out.println( "Enter EXAM 2 Grade: ");
exam2 = keyboard.nextInt();
System.out.println( "Enter EXAM 3 Grade: ");
exam3 = keyboard.nextInt();
keyboard.nextLine();
System.out.println( "Bonus work completed [true/false]");
truefalse = keyboard.nextLine();
// adjust exam scores if necesssary
if (truefalse == "true")
{
bool = true;
exam1 = keyboard.nextInt();
exam2 = keyboard.nextInt();
exam3 = keyboard.nextInt();
}
else
{
average = ((exam1+exam2+exam3)/3);
}
Why is the compiler saying
"variable average might not have been initialized"?

You declared your variable but did not strictly initialize it. It is only initialized if the logic of your program dictates that the line average = ((exam1+exam2+exam3)/3); is hit. This doesn't happen if truefalse == "true".
In order to have Java compile it, you can do one of two things.
Initialize your variable to some default value when you declare it, eg double average = 0;
Make sure that no logical pathway precludes the possibility that the variable is initialized. That is, no matter what happens, it gets initialized.
The first option is better. It keeps your code cleaner and more logical, thus easier to maintain. The second option is more implicit than explicit. You probably shouldn't have to go walking through the logic yourself to see how it works out.

You can initialize the double variable average to 0 when you are declaring it.
double average=0;
Reason of this particular error is that you are trying to initialize the variable in if-else block. The variable will not be initialized if condition is not true. If you are using the variable further in your program, you will get run time errors. That is why Java compiler is letting you know that there are possibilities that the variable might be uninitialized
Furthermore it is always a good practice to initialize a local variable when you declare it.

You need to initialize average.
The compiler is complaining because your code might or might not ever reach the else block. Yet, if you use average when it hasn't been initialized, you get an error.
double average = null;
Alternatively, you can initialize average in the if block as well, because if the if block runs and the else doesn't you'll still have an initialized average at the end of the day and the compiler is happy :).
if (truefalse == "true")
{
average = //something;
bool = true;
exam1 = keyboard.nextInt();
exam2 = keyboard.nextInt();
exam3 = keyboard.nextInt();
}
else
{
average = ((exam1+exam2+exam3)/3);
}
Also, as a final note, a good rule of thumb is to use .equals() for any String and == for ints, characters, booleans etc.

Related

How to validate input in my Java program and add the option for the user to run the program again or exit it?

So I have an assignment in my CISP 1 class that requires me to create a program that displays a bar chart comprised of asterisks based on the amount of sales 5 different stores have had. I've got a base made, but I still want to add a loop that validates the input from the user(i.e. throws an error when the user tries to enter a negative number), and I want to add the option to run the program or exit it. I'm just a little lost on how to do all of that, so I figured I'd reach out on this website and ask. I know a lot of this code could be simplified with arrays, but we haven't started studying that yet - so I'm afraid to be messing with something I don't fully understand. Below is my code:
import java.util.Scanner;
public class BarChart
{
public static void main(String[] args)
{
int store1, store2, store3, store4, store5;
Scanner keyboard = new Scanner(System.in);
System.out.println("This program will display a bar chart " +
" comprised of astericks based on five different stores' " +
"sales. 1 asterick = $100 in sales.");
System.out.print("Enter today's sales for store 1: ");
store1 = keyboard.nextInt();
System.out.print("Enter today's sales for store 2: ");
store2 = keyboard.nextInt();
System.out.print("Enter today's sales for store 3: ");
store3 = keyboard.nextInt();
System.out.print("Enter today's sales for store 4: ");
store4 = keyboard.nextInt();
System.out.print("Enter today's sales for store 5: ");
store5 = keyboard.nextInt();
System.out.println("Sales \t Bar Chart");
System.out.println("----- \t ---------");
System.out.print("\nStore 1: ");
for (int num = 0; num < store1; num += 100)
{
System.out.print("*");
}
System.out.print("\nStore 2: ");
for (int num = 0; num < store2; num += 100)
{
System.out.print("*");
}
System.out.print("\nStore 3: ");
for (int num = 0; num < store3; num += 100)
{
System.out.print("*");
}
System.out.print("\nStore 4: ");
for (int num = 0; num < store4; num += 100)
{
System.out.print("*");
}
System.out.print("\nStore 5: ");
for (int num = 0; num < store5; num += 100)
{
System.out.print("*");
}
}
}
I've tried adding if statements each time the user is asked to enter a sales amount, but that didn't work.
I still want to add a loop that validates the input from the user(i.e.
throws an error when the user tries to enter a negative number)
Here's a quick example that shows how to ask again when an invalind number is entered:
do {
System.out.print("Enter today's sales for store 1: ");
store1 = keyboard.nextInt();
if (store<0) {
System.out.println("Sales must be non-negative!");
}
while (store<0);
I want to add the option to run the program or exit it.
This would be similar to the do { ... } while( ... ); above except you'd put the whole program from below the Scanner line inside the body of the do loop. Then you just ask at the bottom if they want to start over and write your conditional statement in the while portion appropriately.
pls take the time to read through
Solution to the problem
do-while loop
What you're looking for is a while loop that this answer suggests, however you can specify whether to force the user to retry, or break the program and throw an error.
If you'd like to make the user retry and not throw an error that makes the program break, possibly with a retry message every time the user inputs negative numbers, you can use a do-while loop. The do-while loop will execute as "do this then check" rather than the while loop being "check than do this" (you can ensure that your code is more concise this way).
The do-while loop version:
int input; // Declare the variable to be initialized inside the do {} block.
int storeSales; // You can just relax and declare here.
do { // This is the start of the do-while loop
System.out.print("..."); // Your prompt goes here
storeSales = scanner.nextInt(); // Grabbing input from the user
if (storeSales < 0) { // Checking if the input is smaller than 0
System.out.print("..."); // Your message when input is invalid
}
} while (storeSales < 0); // The condition goes here
The caveat of the do-while loop for situations like this is for having conditions in the while loop that the do block will be always executed at least once, requires a variable that isn't initialized first but initialized in the loop itself. Initializing a "user input" variable but then giving it a value of "value that makes a statement work" makes the code awkward and dirty.
while loop
The while loop version will look like this:
int storeSales = -1; // You have to initialize first here, since the while is checked first.
while (storeSales < 0) { // Awkward!
System.out.print(""); // Your prompt goes here
storeSales = scanner.nextInt(); // Grabbing input from the user
if (storeSales < 0) { // Checking if the input is smaller than 0
System.out.print(""); // Your message when input is invalid
}
}
Exceptions
If instead, you'd like to break the program when the input is invalid (smaller than 0):
Introducing the throw statement:
Try this code out:
public class BarChart {
public static void main(String[] args) {
System.out.println(5 / 0);
}
}
You'll yell at me: WTF is this, you're making a program that throws ArithmeticException runtime exception! Division by 0 doesn't make sense!
Well, that's the point. Exceptions in Java are those that happen during runtime because of some condition that doesn't have to do with syntax, clear mistakes like String x = 0, etc. That's the kind of exception you're looking for. To throw such an error similar to the example above , use the throw statement and don't use a loop:
int storeSales = scanner.nextInt();
if (storeSales < 0) {
// Since the exception is related to math, you can use something like ArithmeticException. Your choice though.
throw new ArithmeticException(); // An exception is also an object, so you initialize it that way.
}
CAVEAT, Java doesn't expect exceptions in the first place, and so you have to declare that your method throws exceptions. Even main(). And when you call OTHER methods that ALSO have exceptions, you either have to handle them with a try-catch block, or leave it and add the exceptions to the method definition. But that's for another day I guess.
General improvements
You're doing the same thing, same code, same names (essentially), same print() statements a hard-coded 5 times! You can use a for loop. Unless your names have to be unique and declared separately (which I digress, you names are literally store1, store2, store3, etc.) you can just use a general, reinitialized variable name in every iteration of the for loop.
You can also scan the user input about how many stores (instead of hard-coding 5) to show the data, to make the program completely soft-coded and dynamic (The assignment probably doesn't require you this, refactor the code to your needs)
This code below will be grabbing the user input, then printing it out INSTANTLY AFTER. Now that I look at your solution, maybe it was right after all to define separate variables instead of putting the input in an array, since you want all the input at once then print everything at once.
Here's how it goes:
// You'd want to reformat the code to your preference.
import java.util.Scanner;
public class BarChart {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int storeCount = scanner.nextInt();
for (int i = 0; i < storeCount; i++) { // A loop that repeats 5 times.
// Choose one of the three solutions above and insert them here, I choose the do-while since it's the cleanest
int storeSales;
do {
// You can "concatenate" strings (numbers becomes themselves but in text)
System.out.print("Enter today's sales for store " + (i + 1) + ": ");
storeSales = scanner.nextInt();
if (storeSales < 0) {
System.out.print("Sales cannot be negative, please try again");
}
} while (storeSales < 0);
// Now that the storeSales value has been definitely initialized (or you chose the exceptions solution, I don't blame you) the printing goes here.
System.out.println("Store " + (i + 1) + "'s sales:");
for (int j = 0; j < storeSales; j += 100) {
System.out.print("*");
}
System.out.println();
}
}
}
There's not much to do with your code otherwise, since without the use of arrays, the best you can do is define separate variables, then having a method or two (a reusable piece of code with a name) to do the inputting and printing job for you to make the code cleaner and less repetitive.
In the end, just choose one of the three solutions and apply them to each of your variables. Your code is quite good (if it's intended this way). CHEERS!
oh my god someone read till the end of the post i love you
Scanner keyboard = new Scanner(System.in); // initialize scanner
while (true) { // infinite loop starts
<Do something...> // here you can do the things you need to do (e.g., change variables or record input)
if (condition) { // condition for exiting the loop (e.g., input of positive number)
break; // exiting infinite loop
} // end of IF statement
} // end of WHILE statement
You can use it as separate method and validate each input. It will not let the user to proceed until the valid value will be inputted.

Input from a method gets stuck in java

In this method, it prompts the user to enter the value of their insured home. For some reason, it is getting stuck when the user inputs
static double promptHomeInsVal(){
double homeInsVal;
className promptHomeInsVal = new className();
do{
do{
System.out.printf("%nPlease enter the insured value of your home: ");
homeInsVal = promptHomeInsVal.input.nextDouble();
validateNumber(!promptHomeInsVal.input.hasNextDouble());
}while(promptHomeInsVal.repeat == true);
homeInsVal = promptHomeInsVal.input.nextDouble();
if(homeInsVal <= 0){
System.out.println("The insured value of your home cannot be less than or equal to 0. ");
promptHomeInsVal.repeat = true;
}
else{
promptHomeInsVal.repeat = false;
System.out.println("Home insurance value == " + homeInsVal);
}
}while(promptHomeInsVal.repeat == true);
return homeInsVal;
}
Here is validateNumber()
static void validateNumber(boolean repeat){
className validateNumber = new className();
if(repeat == true){
System.out.println("Warning: You entered an invalid integer or floating-point value. ");
}
}
When the prompt comes up "Please enter the insured value of your home: " it is suppose to take the input and move on. Right now, it is getting stuck
I feel that a significant part of the code is missing, and as far as I can see the problem should be in that part of the code. You should include into your question the code of the class className (which seems to be an error by itself).
In addition to that, I see some minor coding style mistakes in your code. You did not ask for such advice, but let me note that anyBooleanVariable == true is just the same as anyBooleanVariable.
Also validateNumber is the name of a method and the same time the name of a local variable inside the same named method. It is possible, but this is confusing and not a recommended practice.

How to find out which variable is throwing an exception?

I'm writing a program that culculates tip and total from bill and tip rate.
public void takeUserInput() {
Scanner sc = new Scanner(System.in);
double billAmount;
int tipRate;
try {
System.out.print("What is the bill? ");
billAmount = sc.nextDouble();
System.out.print("What is the tip percentage? ");
tipRate = sc.nextInt();
tc.calculate(billAmount, tipRate);
} catch (InputMismatchException e1) {
String errorMessage = "Please enter a valid number for the ";
// errorMessage += billAmount or
// errorMessage += tipRate ?
}
I'm looking for a way to find out which variable throws InputMismatchException, so I can add which variable name into variable errorMessage and print to the screen.
There are various simple ways to get there:
Call hasNextXxx() prior calling nextXxx().
If you go for one try/catch block per input, it is very clear within your catch block which variable caused the problem (you could then call a generic method with a specific error message to avoid code duplication)
You could use reference types for your variables; if you use Double / Integer instead of double / int ... you could check which of the two variables is still null
You put in a little boolean variable, like billAmountIsValid. Initially that variable is false, you turn it to true after the call to nextDouble(). Then you can easily check in your try block whether you got a valid billAmount.
After some more thinking: you really want a combination of 1 + 2: you see; when the users enters a correct billAmount; why would you want to forget about that value when the second value gives a bad second value? No - you should be looping for each variable, until you receive a valid input. And only then you start asking for the next value!
The variable isn't throwing the exception, the evaluation of the right hand side of the variable assignment is, and so there is no information in the exception to say which variable it was about to assign that to had it succeeded.
What you could consider instead is a new method that encompasses the prompting messages and retries:
billAmount = doubleFromUser(sc, "What is the bill? ", "bill");
Where doubleFromUser is:
static double doubleFromUser(Scanner sc, String prompt, String description){
while(true) { //until there is a successful input
try {
System.out.print(prompt); //move to before the loop if you do not want this repeated
return sc.nextDouble();
} catch (InputMismatchException e1) {
System.out.println("Please enter a valid number for the " + description);
}
}
}
You will need a different one for int and double, but if you have more prompts, you will save in the long run.

Is there another way to use hasNextInt() in Java without putting everything in the if-statement?

My objective is to make sure the user inputs an int. Else, exit the program. Then I do some coding that requires that int.
Code Snippet :
Scanner input = new Scanner(System.in);
if (input.hasNextInt()) {
//check if user enters an int
int userinput = input.nextInt();
// assign that int input to variable userinput
// over 100+ lines of code using nextInt var "userinput"
} else {
System.exit(1);
// user did not enter an int
}
Is there a better way to check for whether a user has entered an int and then use that int that doesn't require my entire program to be coded into that if-statement (because nextInt's scope is limited to that if-statement)?
It feels messy to me to put everything into one if-statement.
I wouldn't be allowed to use separate objects/classes since it's early in the semester for my class. This all goes in the main method, and I'm just using simple if-statements/scanner inputs.
Thanks
Definitely! Just negate the if statement and early exit:
Scanner input = new Scanner(System.in);
if (!input.hasNextInt()) {
System.exit(1);
}
// "else"
doMagicalThings(input.nextInt());
Oh, I guess also to note: replace the 100 lines of code with a method call and break it up a bit. That'd be good to do in addition to the above.
Here is a simple example of using hasNextInt () to validate a positive integer input
Scanner input = new Scanner(System.in);
int number;
do {
System.out.println("Input Number ");
while (!input.hasNextInt()) {
System.out.println(" not a number!");
input.next();
}
number = input.nextInt();
} while (number <= 0);
System.out.println("Númber válid " + number);

java Local variable not initializing outside if-statement

Eclipse says that the variable age, agirl and aboy may not have been initialized. I initialized the variables before the first if statement and they got values in the if-statement. When I want to use them in the next if-statement eclipse says the local variables may not have been initialized.
Here is my code:
import java.util.Scanner;
class Main{
public static void main(String args[]){
Scanner input = new Scanner(System.in);
String define;
int aboy, agirl, age;
System.out.println("Are you a boy or a girl?");
define = input.next();
if (define.equals("boy")){
System.out.println("What is your age?");
aboy = input.nextInt();
age = aboy;
}else if (define.equals ("girl")){
System.out.println("What is your age?");
agirl = input.nextInt();
age = agirl;
}else
System.out.println("wrong answer");
if (agirl >= 18 || aboy >= 16){
System.out.println("You are a " + define + " and you are " + age + " years old");
}
}
}
This line
int aboy, agirl, age;
contains declarations, not initializations. Java will not initialize a local variable for you, and there is an execution path (the else) where nothing is ever assigned to those variables, then you attempt to reference their nonexistent values.
You must set values to them before you use them, in all execution paths. Initialize them to something when you declare them.
Not only may you have an uninitialized variable, you're guaranteed to.
Look at your control flow: You first ask for a value for define, and then you execute exactly one of the blocks. If define is "boy", you don't initialize agirl; if define is "girl", you don't initialize aboy, and if define doesn't match either, you don't initialize any of your variables at all.
It looks like you are trying to cleverly combine the functions of a boolean and an int by having "magic" values in your ints. This is poor design because it's not clear how the magic works, but you can make your example run by initializing all of your int values to 0:
int aboy = 0, agirl = 0, age = 0;
Initializing is assigning the variable a value. Declaring is creating the variable. They are not the same.
The reason you need to initialize the variables is because it is possible they will not be initialized. All the if statements could be false, thus you need to give them a default value.

Categories