3

For beginner practice I'm trying to create a simple loop that accepts a single character from the user, prints that character to the console and keeps doing that until the user enters 'R'.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SimpleLoop { class Program { static void Main(string[] args) { char cplayerSelection = 'R'; while(cplayerSelection == 'R') { Console.WriteLine("Enter R, P, or S:"); cplayerSelection = (char)Console.Read(); Console.WriteLine(cplayerSelection); } } } } 

How ever no matter what the user enters it only loops once end then exits. What do I need to change to continue the loop?

4
  • 1
    You can try Console.ReadKey() Commented Feb 12, 2014 at 20:33
  • @SamLeach: No, he wants ==. Did you read his question? The actual text? Where he describes what he wants? Commented Feb 12, 2014 at 20:47
  • @ColinDeClue, yep. Maybe you should re-read it? The loop exit condition is "character other than 'R'". It doesn't loop because anything other than 'R' exits the loop. Commented Feb 12, 2014 at 21:08
  • @SamLeach which is what he wants, however the code above also exits when 'R' is entered. Commented Feb 12, 2014 at 21:35

6 Answers 6

5

I believe that it should be

while(cplayerSelection != 'R' || cplayerSelection != 'r') 

You have to check for both the uppercase and lowercase letter since they do not have the same value.

Edit: Also change the cplayerSelection declaration to some other letter so the loop can actually be executed for the first time.

Also replace this line

cplayerSelection = (char)Console.Read(); 

with

cplayerSelection = Console.ReadKey().KeyChar; 

Read the comment by Habib on this answer as to understand why.

Sign up to request clarification or add additional context in comments.

1 Comment

The OP would also need Console.ReadKey().KeyChar, Selman22 was right about it. But unfortunately he deleted the answer., Because after the first iteration it will receive the character for carriage return and terminate the loop after first iteration.
4

Try this one, inside of your while loop:

cplayerSelection = Console.ReadKey().KeyChar 

That will only work if you type uppercase R

If you want to allow three letters then you can try:

var letters = new[] {'R', 'P', 'S'}; while (letters.Contains(cplayerSelection)) { Console.WriteLine("Enter R, P, or S:"); cplayerSelection = Console.ReadKey().KeyChar; Console.WriteLine(cplayerSelection); } 

If you want to make a case-insensitive check simply add lower-case versions of these characters to the array.Or you can use this (suggested by @Habib):

while (letters.Any(r => r == char.ToUpper(cplayerSelection))) 

5 Comments

+1, and you were right about ReadKey().KeyChar because otherwise the loop will exit on the 2nd iteration,
For case insensitive he could also use ToUpper during the test. while (letters.Contains(Char.ToUpper(cplayerSelection))
@tonyriddle yes but he/she should convert that char to string first.then use ToUpper and convert ToChar again because it is a char array.so ToUpper seems easy but it's painful.adding three extra character to the array is much easier
for char insensitive comparison, the OP can use while (letters.Any(r=> r == char.ToUpper(cplayerSelection)))
@Selman22, there is char.ToUpper and safer Char.ToUpperInvariant
2

Console.Read only reads a single character. The next time you get in the loop, it reads the return character, as well. You have a couple of options, based on whether you want the user to have to hit enter or not.

If you want them to hit enter:

char cplayerSelection = 'R'; while (cplayerSelection == 'R') { Console.WriteLine("Enter R, P, or S:"); cplayerSelection = (Console.ReadLine())[0]; Console.WriteLine(cplayerSelection); } 

If you don't want them to hit enter:

char cplayerSelection = 'R'; while (cplayerSelection == 'R') { Console.WriteLine("Enter R, P, or S:"); cplayerSelection = Console.ReadKey().KeyChar; Console.WriteLine(cplayerSelection); } 

Comments

2

As others have mentioned, you need to be wary of case sensitivity. You can do so by checking the input with both the upper and lower case of the char. Or you could convert the char to its upper/lower-case form and only compare to that.

Also, for programs that always execute at least once like yours, using do while is more appropriate. For example:

class Program { static void Main() { char input; do { input = char.ToUpperInvariant(Console.ReadKey().KeyChar); } while (input != 'R'); } } 

Comments

2

I think you are confused.

...loop that accepts a single character from the user, prints that character to the console and keeps doing that until the user enters a character other than 'R'.

The loop exit condition is any character that is not 'R'. In other words, the only input that continues the loop is 'R'.

no matter what the user enters it only loops once end then exits. What do I need to change to continue the loop?

This is what your first statement means.

What do I need to change to continue the loop?

Change the loop exit condition.

Comments

1

According to this http://social.msdn.microsoft.com/Forums/vstudio/en-US/5c5b43e2-4536-4411-a34f-290eb8525b4d/why-does-consolereadline-not-wait-for-user-input?forum=csharpgeneral, Console.Read() will return a single character. The second time through the loop it will pull your 'return' character and exit your loop.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.