Cannot convert system.consolekeyinfo to string - c#

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.

Related

Trying to convert bool type to char of [yY, nN]

I've new to c# and I've been working on this assignment to take multiple inputs from the user, store the data, then return the data in a certain format. Part of the assignment requirements is to prompt the user to enter a Y or N while it'll accept y or n as well. Is it cordless? [Y or N]:
I've tried using Convert.ToChar(Console.ReadLine().ToLower()); but I keep receiving
cannot implicitly convert char to bool
You can try this:
var userInput = Console.ReadLine().ToLower();
var cordless = userInput == "y";
or
var cordless = Console.ReadLine().ToLower() == "y";
It'll accept Y/y as true otherwise it'll be false
Console.Write("Is it cordless? [Y or N]: ");
string userInput = Console.ReadLine();
if (userInput == "Y")
{
hasCord = true;
}
else if (userInput == "y")
{
hasCord = true;
}
Now that I've seen your answer, I understand your question.. I would have made a method that asks for a string and repeats the question if the input is bad:
public string AskString(string q, string validAnswers[]){
while(true) {
Console.Write(q);
string input = Console.ReadLine();
if(validAnswers == null){
return input; //if no restriction, every answer is valid
} else {
foreach(string a in validAnswers) {
if(input.Equals(a, StringComparison.OrdinalIgnoreCase)){
return input;
}
}
}
}
}
And then use it for every question:
string drillMake = AskString("make? ", null);
string warranty = AskString("warranty, enter 12,24 or 36? ", new string[] {"12", "24", "36"})
string cordless = AskString("cordless, enter Y or N? ", new string[] {"y", "n"});
bool cordlessBool = cordless.Equals("y", StringComparison.OrdinalIgnoreCase);

do-while loop does not go through while condition C#

I wrote a do-while loop but it does not run through while condition somehow.
When I type in invalid characters it should go back to beginning and repeat as it's supposed to.
I ran the code step by step on Visual Studio and it shows that code does not even go through while condition. (no matter what the input value is)
Can someone please help me?
Many thanks in advance!
using System;
using static System.Console;
namespace a5
{
class Program
{
const string acceptedLetters = "EHLNTXZ";
static void Main(string[] args)
{
GetUserString(acceptedLetters);
ReadKey();
}
static string GetUserString(string letters)
{
string invalidCharacters;
do
{
invalidCharacters = null;
Write("Enter : ");
string inputCharacters = ReadLine();
foreach(char c in inputCharacters)
{
if(letters.IndexOf(char.ToUpper(c))==-1)
{
invalidCharacters = c.ToString();
}
}
if(invalidCharacters != null)
{
WriteLine("Enter a valid input");
}
return inputCharacters;
} while (invalidCharacters != null);
}
}
}
The problem is that you return the inputed string at the end of the loop no matter the validation done.
You can use a boolean to check this validity.
Also you don't need to parse all the string and you can break the inner loop on the first invalid char.
I renamed the string as result to use a standard pattern and to be more clean.
For example:
static string GetUserString(string letters)
{
string result;
bool isValid;
do
{
Console.Write("Enter : ");
result = Console.ReadLine();
isValid = true;
foreach ( char c in result )
if ( letters.IndexOf(char.ToUpper(c)) == -1 )
{
isValid = false;
Console.WriteLine("Enter a valid input");
break;
}
}
while ( !isValid );
return result;
}
The line return inputCharacters; makes it leave the loop.
I think you meant:
} while (invalidCharacters != null);
return inputCharacters;
using System;
using static System.Console;
namespace a5
{
class Program
{
const string acceptedLetters = "EHLNTXZ";
static void Main(string[] args)
{
GetUserString(acceptedLetters);
ReadKey();
}
static string GetUserString(string letters)
{
string invalidCharacters;
do
{
invalidCharacters = null;
Write("Enter : ");
string inputCharacters = ReadLine();
foreach(char c in inputCharacters)
{
if(letters.IndexOf(char.ToUpper(c))== -1)
{
invalidCharacters = c.ToString();
}
}
if(invalidCharacters != null)
{
WriteLine("Enter a valid input");
}
} while (invalidCharacters != null);
return inputCharacters;
}
}
}

Caesar cipher - Trouble with negative numbers in the shift key

When I use a negative number for the shift like -1 and use the char 'a', I'm supposed to get 'z' but I get ` instead. How can I fix this?
using System;
using System.IO;
namespace CaesarCipher
{
class Program
{
public static char cipher(char ch, int key)
{
if (!char.IsLetter(ch))
{
return ch;
}
char d = char.IsUpper(ch) ? 'A' : 'a';
return (char)((((ch + key) - d) % 26) + d);
}
public static string Encipher(string input, int key)
{
string output = string.Empty;
foreach (char ch in input)
output += cipher(ch, key);
return output;
}
public static string Decipher(string input, int key)
{
return Encipher(input, 26 - key);
}
static void Main(string[] args)
{
bool Continue = true;
Console.WriteLine(" Ceasar Cipher");
Console.WriteLine("-------------------------\n");
while (Continue)
{
try
{
Console.WriteLine("\nType a string to encrypt:");
string UserString = Console.ReadLine();
Console.Write("\nShift: ");
int key = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("\nEncrypted Data: ");
string cipherText = Encipher(UserString, key);
Console.WriteLine(cipherText);
Console.Write("\n");
Console.WriteLine("Decrypted Data:");
string t = Decipher(cipherText, key);
Console.WriteLine(t);
Console.WriteLine("\nDo you want to continue?");
Console.WriteLine("Type in Yes to continue or press any other key and then press enter to quit:");
string response = Console.ReadLine();
Continue = (response == "Yes");
}
catch (FormatException ex)
{
Console.WriteLine("You entered a bad operation, try another one");
}
}
}
}
}
Ceasar Cipher
Type a string to encrypt:
Hello how are you?
Shift: 1
Encrypted Data:
Ifmmp ipx bsf zpv?
Decrypted Data:
Hello how are you?
Do you want to continue?
Type in Yes to continue or press any other key and then press enter to quit:
Yes
Type a string to encrypt:
Hello how are you?
Shift: -1
Encrypted Data:
Gdkkn gnv `qd xnt?
Decrypted Data:
Hello how `re you?
Do you want to continue?
Type in Yes to continue or press any other key and then press enter to quit:
` is the character that proceeds "a" in the ASCII/Unicode character list. https://unicode-table.com/en/
You'll want to detect if you're trying to shift "a", and instead replace it with "z"
There are many ways you could do this. One way would be to subtract from the last letter the difference if the result is less than the first letter:
public static char cipher(char ch, int key)
{
if (!char.IsLetter(ch))
{
return ch;
}
char firstLetter = char.IsUpper(ch) ? 'A' : 'a';
char lastLetter = char.IsUpper(ch) ? 'Z' : 'z';
int result = ch + key;
if (result < firstLetter) result = lastLetter - (firstLetter - result + 1);
return (char)result;
}

Checking each value of a console output

I would like to read each value one by one, every single one they keep typing until they press a value which ends the "input checking".
I have checked several other posts but none works for me, because I don't want to use arrays or lists, the value must be checked once, and if that happens then work with that.
I have managed to achieve this:
char END = '#', value;
bool found= false;
int count = 0;
Console.WriteLine("Write a line ending in '#'.");
value = Convert.ToChar(Console.Read());
if (value == END)
found = true;
while (!found)
{
count++;
value = Convert.ToChar(Console.Read());
if (value == END)
found = true;
}
}
Console.WriteLine("You have typed " + count);
You should use StringBuilder object, you can add characters one by one to it. I have also simplified your logic a lot.
char END = '#';
var sb = new StringBuilder();
Console.WriteLine("Write a line ending in '#'.");
while (true)
{
var ch = Convert.ToChar(Console.Read());
if (ch == END)
break;
sb.Append(ch)
}
}
Console.WriteLine("You have typed " + sb.ToString());
Something like this.
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
Console.WriteLine("Write a line ending in '#'.");
ConsoleKeyInfo keyInfo;
do
{
keyInfo = Console.ReadKey();
// Evaluate Input Key
if (int.TryParse(keyInfo.Key.ToString(), out int i))
{
; // do something with an int
}
else
{
; // do something with char
}
if (keyInfo.KeyChar != '#')
{
sb.Append(keyInfo.KeyChar);
}
}
while (keyInfo.KeyChar != '#');
Console.WriteLine();
Console.WriteLine($"You typed '{sb.ToString()}' which is {sb.Length.ToString()} character(s).");
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}

Cannot implicitly convert type 'string' to 'int'

I'm doing an athlete program and I want to make int salaryCounter = athleteSalary.ToString so when the user enters the salary of the hired professional I can subtract it from the salary of the athlete and print out how much the athlete will have left but when I try to do it the program tells me "Cannot implicitly convert type 'string' to 'int' ". Can someone help me?
{
Console.WriteLine("Please enter the first name of the athlete");
String athleteString = Console.ReadLine();
Console.WriteLine("Please enter the second name of the athlete");
String athleteString2 = Console.ReadLine();
Console.WriteLine("Did you type {0} {1}? Press y for yess n for no.", athleteString.ToString(), athleteString2.ToString());
ConsoleKeyInfo KeyInfo = Console.ReadKey();
if (KeyInfo.KeyChar == 'y')
{
Console.WriteLine("Enter the salary of {0} {1}", athleteString.ToString(), athleteString2.ToString());
String athleteSalary = Console.ReadLine();
Console.WriteLine("{0} Is this right?", athleteSalary.ToString());
ConsoleKeyInfo rightathleteSalary = Console.ReadKey();
int salaryCounter = athleteSalary.ToString();
if (rightathleteSalary.KeyChar == 'y')
{
Console.WriteLine("Ok. Lets contiune.");
athleteSalary = Convert.ToString(salaryCounter);
Console.WriteLine(salaryCounter);
int counter = 0;
Console.WriteLine("{0} {1} {2}", athleteString.ToString(), athleteString2.ToString(), salaryCounter.ToString());
Console.WriteLine("Enter the hired help. The max number of people is five. Press any key to start.");
while (counter < 5)
{
Console.ReadKey();
Console.WriteLine("Please enter the first name of the hired help");
String hiredhelpString = Console.ReadLine();
Console.WriteLine("Please enter the Last name of the hired help");
String hiredhelpString2 = Console.ReadLine();
Console.WriteLine("Did you type {0} {1}? Press y for yess n for no.", hiredhelpString.ToString(), hiredhelpString2.ToString());
ConsoleKeyInfo KeyInfo5 = Console.ReadKey();
if (KeyInfo5.KeyChar == 'y')
{
Console.WriteLine("Enter the salary of {0} {1}", hiredhelpString.ToString(), hiredhelpString2.ToString());
String hiredhelpSalary = Console.ReadLine();
Console.WriteLine("{0} Is this right?", hiredhelpSalary.ToString());
ConsoleKeyInfo rightSalary = Console.ReadKey();
if (rightSalary.KeyChar == 'y')
{
Console.WriteLine("Ok. Lets contiune.");
}
Console.WriteLine("Record this proffesional? Press y for yess n for no.");
ConsoleKeyInfo RecordKey = Console.ReadKey();
if (RecordKey.KeyChar == 'y')
{
counter = counter + 1;
Console.WriteLine("Number of hired help is {0} They will be paid {1}", counter, hiredhelpSalary);
Console.WriteLine("Press any key to contiune.");
}
else
{
if (RecordKey.KeyChar == 'n')
{
counter = counter - 1;
Console.WriteLine(" Ok. Lets try again. Press any key to contiune.");
Console.ReadKey();
Console.WriteLine("Please enter the first name of the hired help");
String hiredhelpString3 = Console.ReadLine();
Console.WriteLine(" Please enter the Last name of the hired help");
String hiredhelpString4 = Console.ReadLine();
Console.WriteLine("Did you type {0} {1}? Press y for yess n for no.", hiredhelpString.ToString(), hiredhelpString2.ToString());
ConsoleKeyInfo KeyInfo6 = Console.ReadKey();
if (KeyInfo6.KeyChar == 'y')
{
Console.WriteLine("Record this proffesional? Press y for yess n for no.");
ConsoleKeyInfo RecordKey1 = Console.ReadKey();
if (RecordKey.KeyChar == 'y')
{
counter = counter + 1;
Console.WriteLine("Number of Hired help is {0} press any key to contiune", counter);
Console.WriteLine("Press any key to contiune.");
}
}
}
}
/*******************************************************************************************************/
/************************************************************************************************************************************************************************************************************************************************/
}
else
{
if (KeyInfo5.KeyChar == 'n')
{
Console.WriteLine(" Ok. Lets try again. Press any key to contiune.");
Console.ReadKey();
}
}
}
/*************************************************************************************************************************************************************************************************************************************/
Console.WriteLine("");
Console.WriteLine("Athlete's name: {0} {1} Number of Hired help is {2}", athleteString.ToString(), athleteString2.ToString(), counter);
Console.ReadKey();
}
It looks like you're getting confused about variable types. Briefly;
string - stores information character by character. The compiler can't read numbers stored in strings.
int - stores whole numeric values which can be used in calculations.
Your immediate compile problem comes from this line;
int salaryCounter = athleteSalary.ToString();
You're telling the compiler to take altheteSalary which is a string, call the ToString() method which gets the string representation (this is unnecessary when the source is a string) and store the result in an integer.
You need to parse the string to read out the numeric value like this;
int salaryCounter = int.Parse(athleteSalary)
Though, whenever you receive input directly from a user you should code defensively, so instead of int.Parse, use TryParse. That way if your user enters 'Bob' for their salary, you can display an appropriate error;
int salaryCounter;
while(!int.TryParse(athleteSalary, out salaryCounter)
{
Console.Writeline("The salary should be a number, try again");
athleteSalary = Console.ReadLine();
}
Also, you can remove most of the calls to .ToString(), especially where the variable is already a string.
The main issue is that you need to convert your user input to a type other than a string.
There are many ways to do this, but since you are writing a console application that relies heavily on user-entered data, and since some of this data has to be converted to types other than strings, you might consider writing some helper methods that take care of some of the converting and retrying for you.
I've used the following class in several applications with success. Basically, it's just a bunch of methods that accept a string 'prompt' and return a strongly typed result from the user. If the user enters invalid data, then they have to try again until the enter something valid:
class UserInput
{
public static bool GetBool(string prompt)
{
bool result;
List<string> validTrueResponses =
new List<string> {"yes", "y", "true", "t", "affirmative",
"ok", "okay", "yea", "yeah", "yep"};
List<string> validFalseResponses =
new List<string> {"no", "n", "false", "f", "negative",
"never", "not", "nay", "nix"};
while (true)
{
if (prompt != null) Console.Write(prompt);
var input = Console.ReadLine();
if (validTrueResponses.Any(r =>
r.Equals(input, StringComparison.OrdinalIgnoreCase))) return true;
if (validFalseResponses.Any(r =>
r.Equals(input, StringComparison.OrdinalIgnoreCase))) return false;
if (bool.TryParse(input, out result)) break;
Console.WriteLine("Sorry, I don't understand that response. " +
"Please try again.");
}
return result;
}
public static string GetString(string prompt)
{
if (prompt != null) Console.Write(prompt);
return Console.ReadLine();
}
public static int GetInt(string prompt)
{
int input;
while (true)
{
if (prompt != null) Console.Write(prompt);
if (int.TryParse(Console.ReadLine(), out input)) break;
Console.WriteLine("Sorry, that is not valid. Please try again.");
}
return input;
}
public static decimal GetDecimal(string prompt)
{
decimal input;
while (true)
{
if (prompt != null) Console.Write(prompt);
if (decimal.TryParse(Console.ReadLine(), out input)) break;
Console.WriteLine("Sorry, that is not valid. Please try again.");
}
return input;
}
}
Then, I would create a simple class to represent a Person, which has simply a first name, last name, and salary (and override the ToString method to display first and last name):
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public decimal Salary { get; set; }
public override string ToString()
{
return string.Format("{0} {1}", FirstName, LastName);
}
}
Now we can reduce some duplicated code by creating methods to get a Person name and salary. This will prompt the user for the information, and then give them a chance to correct it before commiting the data:
private static void GetPersonName(Person person, string typeOfPerson)
{
if (person == null) throw new ArgumentNullException("person");
if (string.IsNullOrWhiteSpace(typeOfPerson)) typeOfPerson = "person";
bool inputIsGood = false;
while (!inputIsGood)
{
person.FirstName = UserInput.GetString(
string.Format("Please enter the first name of the {0}: ", typeOfPerson));
person.LastName = UserInput.GetString(
string.Format("Please enter the last name of the {0}: ", typeOfPerson));
Console.WriteLine("You entered: {0}", person);
inputIsGood = UserInput.GetBool("Is that correct (y/n): ");
}
}
private static void GetPersonSalary(Person person)
{
bool inputIsGood = false;
while (!inputIsGood)
{
person.Salary = UserInput.GetDecimal(
string.Format("Enter the salary of {0}: $", person));
Console.WriteLine("You entered: {0:C}", person.Salary);
inputIsGood = UserInput.GetBool("Is that correct (y/n): ");
}
}
That may seem like a lot of code, but here's how you can use it in your application:
private static void Main()
{
var athlete = new Person();
GetPersonName(athlete, "athlete");
GetPersonSalary(athlete);
Console.WriteLine("Enter the hired help. The max number of people is five. " +
"Press any key to start.");
Console.ReadKey();
List<Person> hiredHelpers = new List<Person>();
while (hiredHelpers.Count <= 5)
{
bool addAnotherHelper =
UserInput.GetBool(
string.Format("There are currently {0} helpers. " +
"Do you want to add another (y/n): ",
hiredHelpers.Count));
if (!addAnotherHelper) break;
Person helper = new Person();
GetPersonName(helper, "helper");
GetPersonSalary(helper);
bool recordHelper = UserInput.GetBool("Do you want to record this " +
"professional (y/n): ");
if (recordHelper)
{
hiredHelpers.Add(helper);
}
}
Console.WriteLine();
Console.WriteLine("Athlete's name: {0}, salary: {1:C}.", athlete, athlete.Salary);
Console.WriteLine("Number of Hired help is: {0}", hiredHelpers.Count);
Console.WriteLine("Hired help details:");
hiredHelpers.ForEach(h =>
Console.WriteLine(" - Name: {0}, Salary: {1:C}", h, h.Salary));
Console.ReadKey();
}

Categories

Resources