Maintain control of the console input while validating user entry - c#

I need to modify this for a comma-separated string. I want the user to be able to enter multiple numbers but I need to validate they are all numbers before I continue. Any thoughts?
while (!int.TryParse(Console.ReadLine(), out iValue))
{
Console.WriteLine("Please Enter a valid Number!");
}

You can just implemenent custom method for parsing integer arrays and use it in the same way:
void Main()
{
while (!TryParseIntegerArray(Console.ReadLine(), out var arr))
{
Console.WriteLine("Please Enter a valid integer or comma-separated string!");
}
// work with arr here
}
bool TryParseIntegerArray(string input, out int[] arr)
{
if (input == null)
throw new ArgumentNullException(nameof(input));
try
{
arr = input.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToArray();
return true;
}
catch (FormatException)
{
arr = null;
return false;
}
}
However, I wouldn't recomment using Console.ReadLine() directly as an argument, either for TryParseIntegerArray and int.TryParse. You need to check it for null, at least. For example:
string input;
int[] arr;
do
{
input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine($"Good bye!");
return;
}
} while (!TryParseIntegerArray(input, out arr));

What I ended up with
while (true)
{
try
{
var entry = Console.ReadLine();
List<int> myNumbers = entry.Split(',').Select(int.Parse).ToList();
serializedValue = _unitOfWork.GetSerializedCollection(myNumbers);
Console.WriteLine(serializedValue);
Console.ReadLine();
}
catch (FormatException)
{
Console.Write("You must enter a number.");
continue;
}
break;
}

Related

How do I return to the first input after catching exception? [duplicate]

This question already has answers here:
Need help understanding loops
(8 answers)
Reading an integer from user input
(14 answers)
Closed 2 years ago.
I have 2 try and catch but after the first catch
do
{
Console.Write("x = ");
string str = Console.ReadLine();
if (str.ToLower().Equals("exit"))
{
Console.WriteLine("Program has stopped");
break;
}
else
{
try
{
x = Convert.ToInt32(str);
Console.Write("y = ");
y = Convert.ToInt32(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("Input Int or type 'exit' to stop program");
}
}
if it catches then it moves on to the rest of the code. how do I return to Input another value again after catch
try
{
Console.WriteLine("Do you want to Add, Subtract, Multiply, or Divide ?");
f = Console.ReadLine();
}
catch (ArgumentException)
{
Console.WriteLine("Cannot read string");
}
if (f.ToLower().Equals("add"))
{
sum = x + y;
Console.WriteLine("Result: {0}", sum);
while (true);
Although you shouldn't use exceptions for flow control, and TryParse is a much better way to handle the flow, to answer your question:
You could use a while loop for every input and if the input is validated set its condition to false.
Like:
bool firstTime = true, noValidInput = true;
while(noValidInput)
{
Console.Write(firstTime ? "x = " : "Please input Int or type 'exit' to stop program\n x = ");
firstTime = false;
string str = Console.ReadLine();
if (str.ToLower().Equals("exit") || int.TryParse(str))
noValidInput = false;
}
if (str.ToLower().Equals("exit") ...etc.
another way is make a method to get the input:
private string GetUserInput(string message, string errorMessage)
{
Console.WriteLine(message)
var input = Console.ReadLine();
if (!input.ToLower().Equals("exit") && !input.TryParse(str))
input = GetUserInput(errorMessage + message, "");
return input;
}

Console always writes same numbers

I don't know whats wrong but i keep get the same outcome in console :
111
118
101
114
i solved that problem but now my console doesn't show me anything.
i updated my code!
this is my exercise:
Write a program and ask the user to continuously enter a number or type "Quit" to exit. The list of numbers may include duplicates. Display the unique numbers that the user has entered.
this is my code:
while (true)
{
var numbers = new List<int>();
Console.WriteLine("write a number or type quit if you want to exit, if you want to finish write over: ");
var input = Console.ReadLine();
if (input.ToLower() == "quit")
{
break;
}
if (input.ToLower() == "over")
{
var uniq = new List<int>();
foreach (var other in numbers)
{
Convert.ToInt32(other);
if (!uniq.Contains(other))
{
uniq.Add(other);
Convert.ToInt32(other);
Console.WriteLine(other);
continue;
}
int cifre;
if (int.TryParse(input, out cifre))
{
numbers.Add(cifre);
}
else
{
Console.WriteLine("Invalid input, type 'quit', 'over' or a numeric value");
}
}
}
}
thanks for helping.
I figured it out i just had to copy this line:
var numbers = new List();
to the top of while loop and use practicly everything the same i had at the bignning (because of the loop list wasnt sabving numbers in itself). i will edit my code so you can se rescued exercise.
Hope it helps someone
var numbers = new List<int>();
while (true)
{
Console.WriteLine("enter a number or quit or over");
var input = Console.ReadLine();
if (input == "quit")
{
break;
}
if (input == "over")
{
var uniq = new List<int>();
foreach (var value in numbers)
{
if (!uniq.Contains(value)) {
uniq.Add(value);
}
}
foreach (var numbr in uniq) {
Console.WriteLine(numbr);
}
}
else {
// inpout dodas v numbers
var conv = Convert.ToInt32(input);
numbers.Add(conv);
}
}
}
}
thanks for helping
Looks like there are some issues with the logic of the code. Here is the pseudo code I came up with to help you out:
While (true)
if (quit)
//end program
if (over)
//print out the list of integers
else
if (input is not a number)
continue
if (number is not in list)
//add to list
else
//do nothing
This should help you rewrite the program.
var numbers = new List<int>();
Console.WriteLine("Enter numbers or Quit");
while (true)
{
var value = Console.ReadLine();
if (value == "Quit")
{
break;
}
else
{
if (!numbers.Contains(Convert.ToInt32(value)))
numbers.Add(Convert.ToInt32(value));
}
}
foreach (var number in numbers)
{
Console.WriteLine(number);
}
Before you check whether the user has typed "over", you have already converted the characters in the input data and added them to the list. In other words, you're adding the ASCII character values of 'o', 'v', 'e', 'r' to the numeric list.
Move the "over" check and ensure they do not get added to the list:
while (true)
{
...input stuff
if (input.ToLower() == "quit")
{
break;
}
if (input.ToLower() == "over")
{
...make unique and report
continue;
}
foreach (var number in input)
{
var cifre = Convert.ToInt32(number);
numbers.Add(cifre);
}
}
This will solve your issue of having these same numbers in the list. You might also want to replace your foreach with:
int cifre;
if (int.TryParse(input, out cifre))
{
numbers.Add(cifre);
}
else
{
Console.WriteLine("Invalid input, type 'quit', 'over' or a numeric value");
}
Assuming you want to input a single numeric value each time.

C# how to return to previous statement

Hello im wondering how to return to previous statement in C#
For example i want to show user readline again when he filled it wrong and when he will do it right it will show him the next line of code/statement(in this exam. Console.WriteLine("Hi"))
How could i do it?
int num;
string prvnicislo;
prvnicislo = Console.ReadLine();
while (true)
{
if (int.TryParse(prvnicislo, out num))
{
Convert.ToInt32(prvnicislo);
}
else
{
Console.WriteLine("'{0}' is not int, try it again:", prvnicislo);
prvnicislo = Console.ReadLine();
}
}
Console.WriteLine("Hi");
I think this will work:
int num;
string prvnicislo = Console.ReadLine();
while (!int.TryParse(prvnicislo, out num))
{
Console.WriteLine("'{0}' is not int, try it again:", prvnicislo);
prvnicislo = Console.ReadLine();
}
Console.WriteLine("Hi");
Notice that there is not necessary to use Convert.ToInt32 because if the parsing has been succeed the TryParse method will assign the parsed int value to num.
check the following code snippet
int num;
string prvnicislo;
prvnicislo = Console.ReadLine();
while (true)
{
if (int.TryParse(prvnicislo, out num))
{
Convert.ToInt32(prvnicislo);
break;
}
else
{
Console.WriteLine("'{0}' is not int, try it again:", prvnicislo);
prvnicislo = Console.ReadLine();
}
}
Console.WriteLine("Hi");
Hope this helps
if this can be of any help
string prvnicislo = String.Empty;
bool isEntryWrong = true;
do
{
Console.Write("Enter data: ");
prvnicislo = Console.ReadLine();
int num;
if(int.TryParse(prvnicislo, out num))
{
isEntryWrong = false;
}
else
{
Console.WriteLine("'{0}' is not int, try it again:", prvnicislo);
}
} while (isEntryWrong);
Console.WriteLine("Hi")

Cannot convert system.consolekeyinfo to string

What I'am trying to achieve here is that when you press "1" it will check it against "code_1" and then if it matches it will say "key1 correct" and then check the other codes. But the compiler says
Cannot convert system.consolekeyinfo to string
so I'm wondering how I fix this. Here is the code that I use :
static void Main(string[] args)
{
string first_time = null;
string paktc = "Press any key to continue . . .\r\n";
string code_1 = "1";
string code_2 = "2";
string code_3 = "3";
string code_4 = "4";
if (first_time == null)
{
Console.WriteLine("\r\nYour code is 1234\r\n");
Console.WriteLine(paktc);
Console.ReadKey();
Console.WriteLine("Insert Code Now\r\n");
ConsoleKeyInfo key1 = Console.ReadKey();
if (code_1 = key1)
{
ConsoleKeyInfo key2 = Console.ReadKey();
if (code_2 = key2)
{
ConsoleKeyInfo key3 = Console.ReadKey();
if (code_3 = key3)
{
Console.WriteLine("Key3 Correct\r\n");
ConsoleKeyInfo key4 = Console.ReadKey();
if (code_4 = key4)
{
Console.WriteLine("Key4 Correct\r\n");
Console.ReadKey();
Console.WriteLine(paktc);
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
}
}
The error you are currently getting is because you forgot that:
= and == are NOT the same thing. The first is assignment, the second is comparison.
And you can't assign a string to a ConsoleKeyInfo, or vice versa, and definitely not in an if statement. Even if you had fixed that however, you still can't compare a string to a ConsoleKeyInfo. You can get its KeyChar property and compare that to a char though:
if (keyInfo.KeyChar == myString[0])
is valid (as string can be indexed to get its chars). In your case, you can just use a char and make it much simpler:
if (keyInfo.KeyChar == '1')
ToString() would work. Say we have ConsoleKeyInfo j.
It'll look like string k = j.KeyChar.ToString();
This will do exactly what you want.
So the code will look like:
ConsoleKeyInfo key1 = Console.ReadKey();
if (code_1 == key1.KeyChar.ToString())
{
//Other stuff here as follows.
}
You could even do this.
if (key1.KeyChar.ToString() == "1")
{
//Other stuff here as follows
}
Use Console.Read(); instead, it returns a int witch can be typecasted into a char. Also instead of having 4 strings with one character in them, you can have one string with the full code in it and use it as an array, See the example below
static void Main(string[] args)
{
string pw = "123";
Console.WriteLine("Enter the first digit of the password");
char toTest = (char) Console.Read();
Console.Read();
Console.Read();
if (toTest == pw[0])
{
Console.WriteLine("Enter the second digit of the password");
toTest = (char)Console.Read();
Console.Read();
Console.Read();
if (toTest == pw[1])
{
Console.WriteLine("Enter the third digit of the password");
toTest = (char)Console.Read();
Console.Read();
Console.Read();
}
}
}
The extra Console.Read(); commands are to catch the invisible characters that are inputted when pressing enter.

How to assign a value read from the console to an integer field?

In my hangman game, I am attempting to prompt the user to enter the number of "lives" (or guesses) the player should be given. After I type a number at the prompt, the following error message is displayed:
Cannot implicitly convert type 'int' to 'string'
The following line causes the error:
lives = Console.ReadLine();
The lives field is an integer. How can I correctly assign a user-entered value to an integer field?
Here is my complete code:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
namespace ConsoleApplication6
{
class Hangman
{
//guesses
public static int lives = 5;
//Words for the game
static string[] wordBank = { "study", "cat", "dress", "shoes", "lipstick" };
// Create new ArrayList and initialize with words from array wordBank
static ArrayList wordList = new ArrayList(wordBank);
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Title = "C# Hangman";
Console.WriteLine("Hang man!");
//Gamemenu
string response = "";
do
{
Console.Write("Enter Command (1. Add Words, 2. List Words , 3. Play , 4. Exit) Pick 1-4: ");
response = Console.ReadLine();
switch (response)
{
case "1": AddWord(); break;
case "2": ListWords(); break;
case "3": Play(); break;
case "4": break;
}
} while (response != "4");
}
//add words to list
static void AddWord()
{
Console.Write("Enter the word to add: ");
String temp = Console.ReadLine();
wordList.Add(temp);
Console.WriteLine("{0} was added to the dictionary!", temp);
}
//Display words
static void ListWords()
{
foreach (Object obj in wordList)
Console.WriteLine("{0}", obj);
Console.WriteLine();
}
//How many guesses
static void AskLives()
{
try
{
Console.WriteLine("please enter number of lives?");
//This line gives me the error
lives = Console.ReadLine();
}
catch
{
// if user does not enter a number ask it again
AskLives();
}
}
//Gameplay
static void Play()
{
Random random = new Random((int)DateTime.Now.Ticks);
string wordToGuess = wordList[random.Next(0, wordList.Count)].ToString();
string wordToGuessUppercase = wordToGuess.ToUpper();
StringBuilder displayToPlayer = new StringBuilder(wordToGuess.Length);
for (int i = 0; i < wordToGuess.Length; i++)
displayToPlayer.Append('-');
List<char> correctGuesses = new List<char>();
List<char> incorrectGuesses = new List<char>();
bool won = false;
int lettersRevealed = 0;
string input;
char guess;
AskLives();
while (!won && lives > 0)
{
Console.WriteLine("Current word: " + displayToPlayer);
Console.Write("Guess a letter: ");
input = Console.ReadLine().ToUpper();
guess = input[0];
if (correctGuesses.Contains(guess))
{
Console.WriteLine("You've already tried '{0}', and it was correct!", guess);
continue;
}
else if (incorrectGuesses.Contains(guess))
{
Console.WriteLine("You've already tried '{0}', and it was wrong!", guess);
continue;
}
if (wordToGuessUppercase.Contains(guess))
{
correctGuesses.Add(guess);
for (int i = 0; i < wordToGuess.Length; i++)
{
if (wordToGuessUppercase[i] == guess)
{
displayToPlayer[i] = wordToGuess[i];
lettersRevealed++;
}
}
if (lettersRevealed == wordToGuess.Length)
won = true;
}
else
{
incorrectGuesses.Add(guess);
Console.WriteLine("Nope, there's no '{0}' in it!", guess);
lives--;
}
Console.WriteLine(displayToPlayer.ToString());
}
if (won)
Console.WriteLine("You won!");
else
Console.WriteLine("You lost! It was '{0}'", wordToGuess);
Console.Write("Press ENTER to exit...");
Console.ReadLine();
}
}
}
Your lives field is an integer, but Console.ReadLine returns a string.
You can use Int32.Parse(Console.ReadLine()) to parse the input into an integer. Note that an exception will be thrown if the text entered by the user cannot be interpreted as an integer.
Your catch block will work here and re-prompt. It would be more appropriate to use the Int32.TryParse method:
int tmpLives;
if (Int32.TryParse(Console.ReadLine(), out tmpLives))
{
lives = tmpLives;
}
else
{
AskLives();
}
You want to do something along the lines of:
string livesString = Console.ReadLine();
lives = Convert.ToInt32(livesString);
I'm guessing Console.ReadLine() gives you a string. This will not play ball with your integer lives. You could try this:
lives = Int.Parse(Console.ReadLine())

Categories

Resources