• Post Reply Bookmark Topic Watch Topic
  • New Topic

Java Beginner Help: Sentinel Controlled Loop  RSS feed

 
Kiley Song
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everyone, I just became a member of this wonderful site today, and I'm hoping I can get some answers for a project I'm doing. Now, I may just be overlooking something (which happens all the time to me), but I can't seem to get my code to work correctly.

Essentially, I believe the best way to accomplish my goal is use a while loop, controlled by a sentinel.

In my main class, my program needs to:
1. Greet the user. (Super easy, got that down.)
2. Prompt the user to enter an integer value. (Also done.)
3. Ask the user a series of questions, and then accept the input. (Done!)
4. Allow the user at any point to enter "quit," to exit the program. (Not so much D

When I actually type in "quit." It only ends the program during certain points, and I cannot figure out why, or if I'm even approaching this correctly.

Here is the code I have thus far:


Any help is greatly appreciated, and I look forward to learning from everyone!
 
fred rosenberger
lowercase baba
Bartender
Posts: 12565
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This line:

while (!userCommand.equals("quit")) {

ONLY runs once each time through the loop. So, you reach line 21, and get some user input.

On line 23, you test to see if it is the word "quit" (note: you may want to look into using the equalsIgnoreCase() method). Assuming they entered something else, you go into the loop body. Then ENTIRE body runs - from lines 24 through 42 - before you come back to line 23 and test again. So really, it would only be the last thing you ask that matters.

One thing you could do (and this may not be the best) is write a method that checks the user input. call it each time, and have it return a boolean. Then if the boolean is true, break out of your loop.

 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kiley Song wrote:When I actually type in "quit." It only ends the program during certain points, and I cannot figure out why, or if I'm even approaching this correctly.

Probably because you're only checking for it at certain times (ie, when your loop starts over). Unfortunately, if you want to be able to type "quit" when entering the publisher or date there really is no simple alternative to a break statement.

And this is just something you have to get used to. User input is fiddly, and there really is no simple way around it. You can rationalise it for certain types of input (eg, numeric), but there really isn't any way to cover all the possible stupid things they might do. It's a dialogue, and it has a very specific structure; and usually it's different for each program you write.

This is just one of the reasons that GUI programs tend to be so enormous (and also one of the reasons I hate them).

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kiley Song wrote:Here is the code I have thus far:...

Just in case you're discouraged by my previous post, there is one thing you can do to help: Make each class responsible for its own construction, including any user dialogues it might need.

From the sound of things, you're creating (or you should be creating) Citation objects, each of which contains a title, publisher, date and city.

And that means that you can put that part of the dialogue in your Citation class's constructor, perhaps something like:
public Citation(Scanner s) { ...
or (possibly even better) in a factory method:
public static final Citation newInstance(Scanner s) { ...
that returns null if the user has finished entering.

It doesn't make the dialogue itself any less fiddly, but at least then it'll be focused on one thing; and your main() method might then look like:
And just BTW, enormous main() methods are not the best idea. Have a look at the MainIsAPain page for a couple of alternative approaches.

HIH

Winston
 
Kiley Song
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alright, so you sort of lost me there. Why can I not just do a simple sentinel loop? Hmmm... Could you explain a little further? Much thanks!
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have got a simple sentinel‑controlled loop; those loops come in two kinds:-
  • 1: while loops, which check their sentinel before the start.
  • 2: do loops, which start and then check the sentinel when they finish.
  • They don't make a loop which checks its continuation condition in its middle. As you have been told, that would require you to write checking code in the middle of the loop. But I don't think that is neceaary.

    What you have written looks like something where you want to run the loop once, then check whether you want it to run again. That is a do loop, which you will doubtless find in your books, or the Java Tutorials. I think you want something like thisNote that equalsIgnoreCase permits you to accept YES or Yes.
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Of course that won't work, because you have fallen into a trap you won't find in any of the books. If you precede a call to nextLine() by a call to nextAnythingElse() (like some Lord High … in Gilbert and Sullivan) on a Scanner, things will go wrong. That is because nextLine doesn't do what you think it does. More details in this old post of mine.
    If you count the lines you are reading from Scanner, you will find you are always reading one line earlier than you think.
    You have a rather poorly‑named local variable called userCommand in your code, but you appear never to use it.
     
    Kiley Song
    Greenhorn
    Posts: 3
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The variable userCommand I use to hold whatever the user inputs. I understand what a while, do while loop are for (thank goodness for that), I think I read incorrectly about what a sentinel loop is. My mistake. However the suggestions here have been wonderful. I see that the way I have things set up may not be the best. Any other suggestions? You have all been wonderful
     
    Winston Gutkowski
    Bartender
    Posts: 10575
    66
    Eclipse IDE Hibernate Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Kiley Song wrote:However the suggestions here have been wonderful. I see that the way I have things set up may not be the best. Any other suggestions?

    Well, for clarification of my previous post only. If you set up a new class called Citation; maybe something like this:
    your main() method would then look like this:
    Do you see what's happened? We've moved the business of entering Citation information and displaying the details to a class that actually encapsulates a complete Citation. We haven't reduced the amount of code - again, user input is just plain fiddly - but we've made it much more flexible. And now you can reuse that Citation class anywhere else you like.

    Please understand that I give out complete code solutions very rarely, and this is only ONE way of doing it. There are many others.
    What I'm hoping is that it will help you understand the power of breaking up your code into smaller tasks (and indeed, other classes).

    If there's anything you don't understand about the example, please feel free to ask.

    Winston
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!