10 Replies - 2088 Views - Last Post: 06 April 2011 - 02:26 PM Rate Topic: -----

#1 TheMantis  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 01-April 11

Having trouble with the "sentinel method" of looping (While)

Posted 01 April 2011 - 10:05 PM

Hey everyone, noob here trying to get some help with his homework. I'm taking an introductory Java class, and currently learning about loops. In the lab assignment, I'm supposed to be using the "sentinel method". I was able to get this program to function properly when I was just using the "do...while method", but attempting to use the sentinel method along with the following code, I come across an error while the program is running.

Here's the code:
import java.io.*;
 import java.text.*;//for DecimalFormat class
 import java.util.Scanner;//allows for keyboard input
public class lab7
{
  public static void main(String[] args) throws Exception
  {
	DecimalFormat num = new DecimalFormat("$, ###.00");//creates format string named num for $
	
	int accountNumber;//declare an int for account number
	int oldMeter;//declares an int for old meter reading
	int newMeter;//declares an int for new meter reading
	int kwhUsed;//declares an int for killowatts used per hour
	double billCharge;//declares a double for monthly bill amount
	String customerName;//declares a string for customer name
	String companyName;//declares a string for company name
	String errorMessage;//declares a string for an error message
	String answer;
	char answerChar;
	
	Scanner inputDevice = new Scanner(System.in);//creates scanner object, connects it to the system.in object
	
	companyName="McIntyre Electric Co.";//assigns a value to the string "companyName"
	errorMessage="ERROR: The difference between your old and new KMH meter reading should result in a positive number.";//assigns a value to the string "errorMessage"
	answer="";
	
	System.out.print("Enter your account number: #");//prints message requesting input
	accountNumber = inputDevice.nextInt();//assigns input as a value to the variable
	
	inputDevice.nextLine();//used to allow the next input value be assigned to a string variable
	System.out.print("Enter your name: ");//prints message requesting input
	customerName = inputDevice.nextLine();//assigns input as a value to the variable
	
	System.out.print("Enter the amount of KWH from your previous meter reading: ");//prints message requesting input
	oldMeter = inputDevice.nextInt();//assigns input as a value to the variable
	
	System.out.print("Enter the amount of KWH from your previous meter reading: ");//prints message requesting input
	newMeter = inputDevice.nextInt();//assigns input as a value to the variable
	
	kwhUsed = newMeter - oldMeter;//sets the value of the int "kwhUsed" to be the difference of the equation
	
		if((kwhUsed >= 0))//gives instructions on what to do if "kwhUsed" is a positive number
		{
			if((kwhUsed >= 0) && (kwhUsed<=300))//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is between the range of 0-300
				billCharge = 5;	
			if((kwhUsed >= 301) && (kwhUsed<=1000))//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is between the range of 301-1000
				billCharge = (5+((.03) * (kwhUsed-300)));
			else//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is not between the range of 301-1000
				billCharge = (35+((.02) * (kwhUsed-1000)));
				System.out.println("-----------");//prints a dashed line (added to separate output)
				System.out.println("This program is provided by " + companyName + " for " + customerName + " to calculate monthly electric bills");//prints output
				System.out.println("Your account number is: #" + accountNumber);//prints output
				System.out.println("You entered your old meter reading as: " + oldMeter);//prints output
				System.out.println("You entered your new meter reading as: " + newMeter);//prints output
				System.out.println("You used " + kwhUsed + " KWH this month");//prints output
				System.out.println(num.format(billCharge)+ "is the amount due for your electric bill."); //prints output (main result)
		}
		else//gives instructions on what to do if "kwhUsed" is a negative number
		{
				System.out.println("-----------");//prints a dashed line (added to separate output)
				System.out.println(errorMessage);//prints error
		}
	System.out.println("Would you like to start over?");
	System.out.print("Please enter 'y' or 'n': ");
	answer = inputDevice.nextLine();
	answerChar = answer.charAt(0);
	while (answerChar == 'y')
	{
	System.out.print("Enter your account number: #");//prints message requesting input
	accountNumber = inputDevice.nextInt();//assigns input as a value to the variable
	
	inputDevice.nextLine();//used to allow the next input value be assigned to a string variable
	System.out.print("Enter your name: ");//prints message requesting input
	customerName = inputDevice.nextLine();//assigns input as a value to the variable
	
	System.out.print("Enter the amount of KWH from your previous meter reading: ");//prints message requesting input
	oldMeter = inputDevice.nextInt();//assigns input as a value to the variable
	
	System.out.print("Enter the amount of KWH from your previous meter reading: ");//prints message requesting input
	newMeter = inputDevice.nextInt();//assigns input as a value to the variable
	
	kwhUsed = newMeter - oldMeter;//sets the value of the int "kwhUsed" to be the difference of the equation
	
		if((kwhUsed >= 0))//gives instructions on what to do if "kwhUsed" is a positive number
		{
			if((kwhUsed >= 0) && (kwhUsed<=300))//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is between the range of 0-300
				billCharge = 5;	
			if((kwhUsed >= 301) && (kwhUsed<=1000))//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is between the range of 301-1000
				billCharge = (5+((.03) * (kwhUsed-300)));
			else//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is not between the range of 301-1000
				billCharge = (35+((.02) * (kwhUsed-1000)));
				System.out.println("-----------");//prints a dashed line (added to separate output)
				System.out.println("This program is provided by " + companyName + " for " + customerName + " to calculate monthly electric bills");//prints output
				System.out.println("Your account number is: #" + accountNumber);//prints output
				System.out.println("You entered your old meter reading as: " + oldMeter);//prints output
				System.out.println("You entered your new meter reading as: " + newMeter);//prints output
				System.out.println("You used " + kwhUsed + " KWH this month");//prints output
				System.out.println(num.format(billCharge)+ "is the amount due for your electric bill."); //prints output (main result)
		}
		else//gives instructions on what to do if "kwhUsed" is a negative number
		{
				System.out.println("-----------");//prints a dashed line (added to separate output)
				System.out.println(errorMessage);//prints error
		}
	System.out.println("Would you like to start over?");
	System.out.print("Please enter 'y' or 'n': ");
	answer = inputDevice.nextLine();
	answerChar = answer.charAt(0);
	}
	}
}



Now, the program calculates everything just fine. But once it's all calculated and it comes time to enter input as to whether or not the program should run again, I get the following error:

Exception in thread "main" java.lang.StringIndexOutOfBo
undsException: String index out of range: 0
at java.lang.String.charAt(String.java:686)
at lab7.main(Lab7.java:66)

So apparently the issue is
answerChar = answer.charAt(0);


Now, I have attempted to fix this issue through the good 'ol fashioned google method. I was able to find this post which seems to talk about the same issue:
http://www.bleepingc...opic228997.html
The last post says the following:

Quote

The problem is that after using nextInt(), you are left with input that starts with a newline.

For example, your input will be something like this:
INT\n
CHAR\n

First, you are calling nextInt(), which will leave you with this:
\n
CHAR\n

Now you are calling nextLine(). Since the next character on the input is a newline character, the function returns immediately giving you a string with zero characters in it. You need to flush the rest of that first line away (an extra call to nextLine() should do it).


If this post is the solution, how would I go about putting in an extra call to nextLine()?

Is This A Good Question/Topic? 0
  • +

Replies To: Having trouble with the "sentinel method" of looping (While)

#2 TMKCodes  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 48
  • View blog
  • Posts: 440
  • Joined: 21-March 09

Re: Having trouble with the "sentinel method" of looping (While)

Posted 01 April 2011 - 11:08 PM

inputDevice.nextLine();
answer = inputDevice.nextLine();
answerChar = answer.charAt(0);



You just call extra nextLine() to get rid of the newline character in the buffer.

This post has been edited by TMKCodes: 01 April 2011 - 11:08 PM

Was This Post Helpful? 2
  • +
  • -

#3 TheMantis  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 01-April 11

Re: Having trouble with the "sentinel method" of looping (While)

Posted 02 April 2011 - 06:20 AM

View PostTMKCodes, on 01 April 2011 - 11:08 PM, said:

inputDevice.nextLine();
answer = inputDevice.nextLine();
answerChar = answer.charAt(0);



You just call extra nextLine() to get rid of the newline character in the buffer.

Easy enough! That fixed it =)

Thanks for the help.
Was This Post Helpful? 0
  • +
  • -

#4 I ♣ Seals  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 52
  • Joined: 20-November 10

Re: Having trouble with the "sentinel method" of looping (While)

Posted 02 April 2011 - 11:58 AM

You're overcommenting your code. Comments are good, but a lot of your code speaks for itself, such as the variable declarations and your System.out.println() calls, and having too many comments means that the ones that should be there are less likely to be noticed.
Was This Post Helpful? 0
  • +
  • -

#5 TheMantis  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 01-April 11

Re: Having trouble with the "sentinel method" of looping (While)

Posted 02 April 2011 - 12:57 PM

View PostI ♣ Seals, on 02 April 2011 - 11:58 AM, said:

You're overcommenting your code. Comments are good, but a lot of your code speaks for itself, such as the variable declarations and your System.out.println() calls, and having too many comments means that the ones that should be there are less likely to be noticed.

Thanks for the tip, I will definitely use less comments moving forward when I code for myself. I felt the same way and would prefer not to comment so much, but my teacher requested our programs be "fully commented". Not being completely sure what she meant by this, I comment everything. She hasn't said anything about the comments and has given me good grades, so I've just been doing this every time (I just figured she wants us to comment everything to be sure we know what everything does).

This post has been edited by TheMantis: 02 April 2011 - 12:58 PM

Was This Post Helpful? 0
  • +
  • -

#6 TheMantis  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 01-April 11

Re: Having trouble with the "sentinel method" of looping (While)

Posted 05 April 2011 - 05:57 PM

Ok, so I ended up having to redo the assignment because what I coded the first time around was not a sentinel loop (I was mistaken in my beliefs of what that was).

Anyways, from my understanding, a sentinel loop is a loop that continues until a specific value is assigned to a certain variable. Is this understanding correct?

I've attempted to recode it properly, this is what I've got so far
 import java.io.*;
 import java.text.*;
 import java.util.Scanner;
public class lab7
{
  public static void main(String[] args)
  {
	DecimalFormat num = new DecimalFormat("$, ###.00");//creates format string named num for $
	
	int accountNumber;//declare an int for account number
	int oldMeter;//declares an int for old meter reading
	int newMeter;//declares an int for new meter reading
	int kwhUsed;//declares an int for killowatts used per hour
	double billCharge;//declares a double for monthly bill amount
	String customerName;//declares a string for customer name
	String companyName;//declares a string for company name
	String errorMessage;//declares a string for an error message
	
	
	Scanner inputDevice = new Scanner(System.in);//creates scanner object, connects it to the system.in object
	
	companyName="McIntyre Electric Co.";//assigns a value to the string "companyName"
	errorMessage="ERROR: The difference between your old and new KMH meter reading should result in a positive number.";//assigns a value to the string "errorMessage"
	customerName="";
	
	System.out.println("-----------");//prints a dashed line (added to separate output)
	System.out.println("Welcome to the " + companyName + "bill calculator.");
	
	while (!"exit".equals(customerName))
	{
		System.out.print("If you would like to exit this program, please enter the word 'exit' in now."+ "\n" +"Otherwise, Enter your name: ");//prints message requesting input
		customerName = inputDevice.nextLine();//assigns input as a value to the variable
		System.out.print("Enter your account number: #");//prints message requesting input
		accountNumber = inputDevice.nextInt();//assigns input as a value to the variable
		System.out.print("Enter the amount of KWH from your previous meter reading: ");//prints message requesting input
		oldMeter = inputDevice.nextInt();//assigns input as a value to the variable
	
		System.out.print("Enter the amount of KWH from your previous meter reading: ");//prints message requesting input
		newMeter = inputDevice.nextInt();//assigns input as a value to the variable
	
		kwhUsed = newMeter - oldMeter;//sets the value of the int "kwhUsed" to be the difference of the equation
	
		if((kwhUsed >= 0))//gives instructions on what to do if "kwhUsed" is a positive number
			{
			if((kwhUsed >= 0) && (kwhUsed<=300))//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is between the range of 0-300
				billCharge = 5;	
			else
			if((kwhUsed >= 301) && (kwhUsed<=1000))//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is between the range of 301-1000
				billCharge = (5+((.03) * (kwhUsed-300)));
			else//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is not between the range of 301-1000
				billCharge = (35+((.02) * (kwhUsed-1000)));
				System.out.println("-----------");//prints a dashed line (added to separate output)
				System.out.println("This program is provided by " + companyName);//prints output
				System.out.println("The following information is for the account belonging to " + customerName + ".");//prints output
				System.out.println("Your account number is: #" + accountNumber);//prints output
				System.out.println("You entered your old meter reading as: " + oldMeter);//prints output
				System.out.println("You entered your new meter reading as: " + newMeter);//prints output
				System.out.println("You used " + kwhUsed + " KWH this month");//prints output
				System.out.println(num.format(billCharge)+ " is the amount due for your electric bill."); //prints output (main result)
			}
		else//gives instructions on what to do if "kwhUsed" is a negative number
			{
			System.out.println("-----------");//prints a dashed line (added to separate output)
			System.out.println(errorMessage);//prints error
			}
		inputDevice.nextLine();
	}
	}
}
	

So now my problem is that once i enter exit, the program only exits once you complete all of the prompts that follow it. That's not exactly how I thought a sentinel loop would work, making me think perhaps I'm doing it incorrectly. Am I doing it incorrectly? Is this a sentinel loop? How can I make it so the program exits immediately upon the assigning of the variable customerName as exit?

This post has been edited by TheMantis: 05 April 2011 - 05:58 PM

Was This Post Helpful? 0
  • +
  • -

#7 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8332
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Having trouble with the "sentinel method" of looping (While)

Posted 05 April 2011 - 06:30 PM

these comments are as usefull

System.out.print("Enter your account number: #");//prints message requesting input System.out.println("-----------");//prints a dashed line (added to separate output)
as
i = i + 1; // add 1 to i

You all know what a print/println do

We can't see your code lost in all these comments

       if((kwhUsed >= 0))//gives instructions on what to do if "kwhUsed" is a positive number
            {
            if((kwhUsed >= 0) && (kwhUsed<=300))//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is between the range of 0-300
                billCharge = 5; 
            else
            if((kwhUsed >= 301) && (kwhUsed<=1000))//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is between the range of 301-1000
                billCharge = (5+((.03) * (kwhUsed-300)));
    else//gives instruction to set a value to the variable "billCharge" depending on whether the int variable "kwhUsed" is not between the range of 301-1000



That would make a lot more sense
// evaluate bill charge depending on a limit of 300 and 1000 and > 1000
       if((kwhUsed >= 0) {            {
            if((kwhUsed >= 0) && (kwhUsed<=300))
                billCharge = 5; 
            else if((kwhUsed >= 301) && (kwhUsed<=1000)) 
                billCharge = (5+((.03) * (kwhUsed-300)));
           else
               billCharge = (35+((.02) * (kwhUsed-1000)));


BTW your second if((kwhUsed >= 0) inside the if is useless. Yess kwhUsed if over 0 we have already test it

Commenting your line of code
if(a > 0) // test if a is greater than 0
is completly useless. It is the business rules (that you translate into code) that should be commented. Every body knows that println() prints text and that if(a > 0) test if > 0
Was This Post Helpful? 0
  • +
  • -

#8 TheMantis  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 01-April 11

Re: Having trouble with the "sentinel method" of looping (While)

Posted 05 April 2011 - 06:38 PM

I'm not trying to be a dick, but none of what you posted relates to the problem I'm having at all. It's already been covered that this code is overcommented. It is that way at the request of my teacher.

In the future, I will delete the needless comments before posting my code here.

This post has been edited by TheMantis: 05 April 2011 - 06:40 PM

Was This Post Helpful? 0
  • +
  • -

#9 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8332
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Having trouble with the "sentinel method" of looping (While)

Posted 05 April 2011 - 06:52 PM

View PostTheMantis, on 05 April 2011 - 08:38 PM, said:

I'm not trying to be a dick, but none of what you posted relates to the problem I'm having at all. It's already been covered that this code is overcommented. It is that way at the request of my teacher.

In the future, I will delete the needless comments before posting my code here.

We can hardly see how while() and if matches
One thing for sure thow

	while (!"exit".equals(customerName))  <--- this test on customerName
	{
		System.out.print("If you would like to exit this program, please enter the word 'exit' in now."+ "\n" +"Otherwise, Enter your name: ");
                // even if you enter "exit" here
		customerName = inputDevice.nextLine();
                // you will continue to input the following data
		System.out.print("Enter your account number: #");
		accountNumber = inputDevice.nextInt();
		System.out.print("Enter the amount of KWH from your previous meter reading: ");
		oldMeter = inputDevice.nextInt();
	
		System.out.print("Enter the amount of KWH from your previous meter reading: ");
		newMeter = inputDevice.nextInt();
	
		kwhUsed = newMeter - oldMeter;
	
		if((kwhUsed >= 0))
			{
			if((kwhUsed >= 0) && (kwhUsed<=300))
				billCharge = 5;	
			else
			if((kwhUsed >= 301) && (kwhUsed<=1000))
				billCharge = (5+((.03) * (kwhUsed-300)));
			else				billCharge = (35+((.02) * (kwhUsed-1000)));
				System.out.println("-----------");
				System.out.println("This program is provided by " + companyName);//prints output
				System.out.println("The following information is for the account belonging to " + customerName + ".");
				System.out.println("Your account number is: #" + accountNumber);
				System.out.println("You entered your old meter reading as: " + oldMeter);
				System.out.println("You entered your new meter reading as: " + newMeter);
				System.out.println("You used " + kwhUsed + " KWH this month");
				System.out.println(num.format(billCharge)+ " is the amount due for your electric bill."); 
			}
		else
			{
			System.out.println("-----------");
			System.out.println(errorMessage);
			}
		inputDevice.nextLine();
	}  // <----- until here where your while() finishes
	}
}
	



Better to do a while(true) and break on the condition

	while (true) 
	{
		System.out.print("If you would like to exit this program, please enter the word 'exit' in now."+ "\n" +"Otherwise, Enter your name: ");
                // even if you enter "exit" here
		customerName = inputDevice.nextLine();
		if(customerName.equals("exit"))
                    break;
                ....
         }


Was This Post Helpful? 1
  • +
  • -

#10 TheMantis  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 01-April 11

Re: Having trouble with the "sentinel method" of looping (While)

Posted 05 April 2011 - 07:19 PM

Thank you for your help pbl, this is the sort of response I was looking for. The program now functions as I had wanted it to. :bigsmile:
Was This Post Helpful? 0
  • +
  • -

#11 TheMantis  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 01-April 11

Re: Having trouble with the "sentinel method" of looping (While)

Posted 06 April 2011 - 02:26 PM

UPDATE:
Okay, so I got an e-mail from my instructor today letting me know that while the program functions as it should with the new code that utilizes:
while (true) 
{
	System.out.print("If you would like to exit this program, please enter the word 'exit' in now."+ "\n" +"Otherwise, Enter your name: ");
               // even if you enter "exit" here
	customerName = inputDevice.nextLine();
	if(customerName.equals("exit"))
                   break;
               ....
        }


It is still not what she is looking for from this assignment (up to this point, we have not learned to use things such as break, and she says it should be able to be done without if)
So after a push in the right direction with her saying the following:

Quote

The input has to be before the while so if it is the sentinel value, it will exit. Since it's before the while, it is not part of the loop so you need to have the same input again at the bottom of the loop.

I ended up adjusting the code, and it now functions both as I had intended and is coded as she wanted.
Here is the final code:
 import java.io.*;
 import java.text.*;
 import java.util.Scanner;
public class lab7
{
  public static void main(String[] args)
  {
	DecimalFormat num = new DecimalFormat("$, ###.00");//creates format string named num for $
	
	int accountNumber;
	int oldMeter;
	int newMeter;
	int kwhUsed;
	double billCharge;
	String customerName;
	String companyName;
	String errorMessage;
	
	
	Scanner inputDevice = new Scanner(System.in);//creates scanner object, connects it to the system.in object
	
	companyName="McIntyre Electric Co."
	errorMessage="ERROR: The difference between your old and new KMH meter reading should result in a positive number.";
	
	System.out.println("-----------");
	System.out.println("Welcome to the " + companyName + "bill calculator.");
	System.out.print("If you would like to exit this program, please enter the word 'exit' in now."+ "\n" +"Otherwise, Enter your name: ");//sentinel variable outside the while loop
	customerName = inputDevice.nextLine();
	while (!"exit".equals(customerName))//while loop using sentinel method
	{
		System.out.print("Enter your account number: #");
		accountNumber = inputDevice.nextInt();
		System.out.print("Enter the amount of KWH from your previous meter reading: ");
		oldMeter = inputDevice.nextInt();
	
		System.out.print("Enter the amount of KWH from your previous meter reading: ");
		newMeter = inputDevice.nextInt();
	
		kwhUsed = newMeter - oldMeter;
	
		if((kwhUsed >= 0))
			{
			if((kwhUsed >= 0) && (kwhUsed<=300))
				billCharge = 5;	
			else
			if((kwhUsed >= 301) && (kwhUsed<=1000))
				billCharge = (5+((.03) * (kwhUsed-300)));
			else
				billCharge = (35+((.02) * (kwhUsed-1000)));
				System.out.println("-----------");
				System.out.println("This program is provided by " + companyName);
				System.out.println("The following information is for the account belonging to " + customerName + ".");
				System.out.println("Your account number is: #" + accountNumber);
				System.out.println("You entered your old meter reading as: " + oldMeter);
				System.out.println("You entered your new meter reading as: " + newMeter);
				System.out.println("You used " + kwhUsed + " KWH this month");
				System.out.println(num.format(billCharge)+ " is the amount due for your electric bill.");
				System.out.println("-----------");
			}
		else
			{
			System.out.println("-----------");
			System.out.println(errorMessage);
			}
		inputDevice.nextLine();
		System.out.print("If you would like to exit this program, please enter the word 'exit' in now."+ "\n" +"Otherwise, Enter your name: ");//sentinel variable within the while loop
		customerName = inputDevice.nextLine();
	}
	}
}
	

This thread has been very useful to me. To those who find this post when googling because they too are having difficulty with the sentinel method of looping, I hope you find it useful as well.

This post has been edited by TheMantis: 06 April 2011 - 02:27 PM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1