• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

While-Loop for ending program from user input

 
Greenhorn
Posts: 10
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

The program I'm trying to make is supposed to act as a test, where users give their name to the program, and then choose a letter (A through F) for each two 'questions', where each letter has a different value. The user is then given a 'grade' that depends on the value of the letter choices. The program will loop until the user chooses to quit and end the program.
If the user gives an invalid input, (any other character or letter not A-F), the program will loop, asking for valid input until it's given. After the program runs all the way through, and the user gets their results, the user clears the screen by hitting enter and the program starts again from the beginning.

Here's the code I have so far:



The program works fine as is, where the user will input the two correct letters, will be prompted for again for two new ones if they aren't the letters a-f, the value of their choices will be calculated, and the user will be given a grade in the end. The program also quits if the user inputs 'q' instead of their name too. Now It's getting the entire code to loop again after it finishes. If I put the while-loop after where the user inputs their name (userName = scan.Next();), the program will loop, but it won't show the prompt for the username again or the choice to quit anymore. It'll begin at the prompt where it says: Please print out two letters. How and where do I put the while and break parts of the code so it will function properly?

Also, neither while (true) or do-while worked either when I tried it. It makes it so the program won't quit on command anymore.
 
Bartender
Posts: 10966
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
On line 19 add
Line 23
Line 92, do away with the else.

I would strongly urge you to clean up your indentation.

Putting some of your logic into their own methods would help make the code clearer.

You'll only ever need one scanner for keyboard so you can create it as a class static constant.
 
Rancher
Posts: 5089
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also please fold the long lines like 29 and 87 so that they can be viewed without having to scroll to the right.
 
Carey Brown
Bartender
Posts: 10966
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One often used approach where user input is required is to put the validation check and loop inside a method. Something like
Then in the main body of your code you can call it like:
And remove all your validation from your main body. Much cleaner.
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The while (true) function seemed to only work the first time around for some reason. When the user prompts for their name when running the code again if 'q' is put in, the program doesn't stop. The while true doesn't function the second time around. I've tried putting the while function at the beginning and wrapping the entire code around that, but The program will declare that userName hasn't been initialized yet. And putting it after won't prompt the user for their name at all anymore, so there's no option to quit. I'm only in about 2 months worth of java so I tend to stick with very basic code, even if it looks bulkier than a more complex code ^^;
 
Carey Brown
Bartender
Posts: 10966
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please post your modified code (with indents cleaned up).
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Most of the code is still the same, I had trouble trying to go against what I had learning from java so far, that using the new code might be confusing. The variable for choiceOne and choiceTwo are fixed so that the conditions wouldn't be too long to read.
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's the somewhat modified code:



The code is also to accept a blank space as an answer, but it has a value of 0.
 
Carey Brown
Bartender
Posts: 10966
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Line 93
You should stick with using scan.nextLine() and stay away from accessing System.in by two different means.
An ASCII 'a' has a numeric value of 97 (decimal). 'f' is 102. A space is 32. So therefore your code would translate to
On line 1, choiceOne can never be greater-or-equal to 97 AND at the same time be less-than-or-equal to 32.

To see if your chars ARE NOT in the range of 'a' through 'f'

Your println("\f"); is also a problem. If you want to output a blank line use

 
Carey Brown
Bartender
Posts: 10966
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You have a potential problem with these lines
If the user just presses Enter with no characters then the charAt(0) will throw an exception. Likewise, if only a single character is entered the charAt(1) will throw an exception. You'll want to check that letterInput.length() == 2 to take some preventative steps. Also, you may want to change the prompt to let the user know not to put a space between the two characters.
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
char c = (char) System.in.read(); and println("\f") were both code elements given by my teacher who said we could use them in our code, so I decided to use them as is. They seemed to work properly too in clearing the screen at the end of the program too.

But the charAt(0) system print ln method was not working at all, this is a better way of going about it. choiceOne and choice Two just need to have an empty character being accepted as a valid input also and that part can be labeled as done for now.
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I thought with my chatAT(0) method, if for example: letterInput = ac, then choiceOne would be charAT(0) which would be 'a' and choiceTwo would be chaAT(1) which would be 'c', since 'a' is the first character of the string which is index 0, and 'c' is the second character which would be index 1
 
Carey Brown
Bartender
Posts: 10966
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You are correct, but if letterInput = a then charAt(1) will throw an exception.
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's a more updated version of the code: where the string for letterInput can only be accepted if its 2 characters long, and the string cannot contain a space because the characters that are accepted have to be two letters from a-f or either character being a blank space.
Also, the code now only runs and will continue to run on a loop when the boolean of runProgram is true. If the user input for [i]userName[/u] is 'q', runProgram will render false, thus preventing the code from running and stopping the loop altogether.



The problem now is the loop itself. On the second run, runProgram is still true, so the code will run again. Problem is, there is no option of giving any user input anymore, it skips that line and proceeds to ask for two letters instead. Some other forums were saying that with a loop, the scan.nextLine() will take the character from the last keystroke (which was empty because the enter key from the last loop was entered) and use it as the new input for the first variable in which the user input is giving value to.  It's been suggested to add another scan.nextLine() line to 'eat' up that empty keystroke, then prompt the user again and take the next input as the value for the string the value is being assigned to. But in doing that, on the very first run, the user is just being prompted for an input for userName twice. It only asks for it once on the second program run. Putting the while loop at the very beginning isn't good either then telling the code to only run if userName is 'q' because it looks for the value of userName to see whether or not its 'q' for it to run, but userName hadn't been given a value yet until the user inputs something for it. But if I put the while loop after the program accepts a value from the user, when it loops, the part to prompt for userName isn't shown at all.
 
Carey Brown
Bartender
Posts: 10966
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is a classic error and is why writing this is a no-no.
You meant to say
but as you found out, if you mistakenly leave out one of the '=' then the behavior changes entirely.
You should instead use
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, the while ( runProgram ) method didn't get the user to quit the program at all and when starting up the program again, since runProgram was never rendered to false again, it just shows please enter your name twice in the beginning. If I don't allow the while loop to run the code as long as runProgram is true, prompting the user for their name the second time around is just completely skipped over.

Here's instead a picture of what's going on with each method:

For the while-loop boolean ( runProgram ) method:



And for the do-while loop and if ( userName is not "q") method:



The prompt to ask for the user's name doesn't show up when running the code after the first time.Code Output

Also, the charAt(0) method isn't working even when prompting the user to only input two letters. I put a while loop so it would only accept 2 characters, but if it isn't 2 characters, or isn't a letter from a-f, the program doesn't loop for a valid answer, instead, it crashes altogether.
 
Sheriff
Posts: 7126
185
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What about:
 
Knute Snortum
Sheriff
Posts: 7126
185
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One of the other problems with your code is the mixing of scan.next() and scan.nextLine().  There are different opinions on this forum about what to do in these cases, but I would recommend changing all scan.next() to scan.nextLine(), especially since you have a "Press Enter key to continue" prompt.
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm sorry for replying a little later than intended, but I'm happy to say that the issues in the code have finally been resolved.  The code is finally running as its supposed to after fixing the problem with the boolean value and the do-while loop.  

I didn't know that you shouldn't use an equals sign for a boolean because that assigns a value to them, not check its condition. And if a value is assigned to them, it becomes permanent and can't change depending on the conditions meant to change it.
Apparently the error where the input on the first line when in a loop wasn't the code itself, but an error brought over from C++, and had to be avoided by adding in an extra scan.nextLine() after the command to prompt the user and assigning their input as the values of the name of the user and their which letters they chose.

But scan.next() didn't scan the entire name if there was a space between two names when I tried it, so it had to stay as scan.nextLine() in the end. But other than that the code runs fine, thank you for all the help ^^

 
Knute Snortum
Sheriff
Posts: 7126
185
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Catherine Christopher wrote:I'm sorry for replying a little later than intended, but I'm happy to say that the issues in the code have finally been resolved.  The code is finally running as its supposed to after fixing the problem with the boolean value and the do-while loop.  


Congratulations!

I didn't know that you shouldn't use an equals sign for a boolean because that assigns a value to them, not check its condition.


That's correct...

And if a value is assigned to them, it becomes permanent and can't change depending on the conditions meant to change it.


That's not correct.  You can change the value of a boolean after you've assigned it a value -- unless it's final.

Apparently the error where the input on the first line when in a loop wasn't the code itself, but an error brought over from C++, and had to be avoided by adding in an extra scan.nextLine() after the command to prompt the user and assigning their input as the values of the name of the user and their which letters they chose.


You shouldn't have to add another scan.nextLine() if you only use scan.nextLine().  Mixing next() and nextLine() is what will get you into trouble

But scan.next() didn't scan the entire name if there was a space between two names when I tried it, so it had to stay as scan.nextLine() in the end.


That's correct, because next() looks for the next "token" and by default, tokens are separated by whitespace (space, tab, etc.).

But other than that the code runs fine, thank you for all the help ^^


You're welcome!
 
Catherine Christopher
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, and sorry for the late reply again. I wasn't sure how to explain myself and decided to just leave it because the code was already submitted and my instructor went over what was wrong. (He gave in to helping everyone since so many of us were having trouble..)
Here's the final running code I submitted with notes:



It runs as it's supposed to, the only thing the instructor had a problem with was the letters at the end not being capitalized first in the final result. He also explained how the charAt(0) method will automatically take in another character as the value of a new one if space is put between each one and that it didn't have to be specified in instructions. He also said that the boolean which was causing the problem also didn't need to be specified as true since its already being read as true as a value. It would be like saying 'if true = true' which wasn't needed. I mistakingly thought that if setting the conditions for a boolean to be true will always make it true instead;;; Using the second scan.nextLine() worked without error, and it didn't cause the code to misbehave, so it was kept. Maybe it was placement, I don't know, but its fine.  So if anyone needs to make a program that runs like this, here's an example you can use from.
 
Marshal
Posts: 80111
414
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Catherine Christopher wrote:. . . . . .

Are you quite sure about that? I don't like continue; but other people are happy to use it. Should you get to that line 27, you will simply break out of the loop. The test will always faill because your boolean will be false. This suggests to me that you didn't need that boolean in the first place. The return; at the end of the method is redundant; the method would complete with or without return;
I would have put the test at either end of the loop. Something like this:-or even:-About the only place where you actually want while (...); with a semicolon. Or code in the same line after a }

here's an example you can use from.

Thank you

Notice how difficult the first code block is to read. That is because you have used a // comment where a /* comment over several lines */ would have been  more appropriate, and because you have written your lines too long.
 
Everybody's invited. Even this tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic