Console.ReadKey(false) in C# something fishy about it - c#

i am trying to make a simple application in C# in which every character I type is displayed in a console window. Here is my code :
class Program {
static void Main(string[] args) {
while (true) {
System.ConsoleKeyInfo input;
input = Console.ReadKey(false);
String d = input.ToString();
char c = d[0];
Console.WriteLine(c);
}
}
}
The problem is that the characters are not displayed correctly, and to be more precise, every character is followed by an 'S'. For example i type 'a' and i get 'aS' instead of 'a'. Any solutions? Thnx in advance!

What you are seeing is the following:
The original character you entered, since you passed false not true to ReadKey
The first characters of the string "System.ConsoleKeyInfo", since the ToString() method returns the typename (here), not the character entered.
Use the following code instead to achieve what you attempted:
while(true)
{
ConsoleKeyInfo info = Console.ReadKey(true);
Console.WriteLine(info.KeyChar);
}

Because input.ToString() == "System.ConsoleKeyInfo" :-)
Depending on what you want to do, try writing input.KeyChar.

The parameter of Console.ReadKey(false); defines if the key you type is intercepted or not. So Console.ReadKey(false); prints the character you type and Console.Writeline(c) prints the S.

Try char c = input.KeyChar; instead.

The problem is that you are using ToString() on a System.ConsoleKeyInfo. When this is turned into a string you will get "System.ConsoleKeyInfo" and the first character is therefore 'S'. Did you mean to write the following code instead?
while (true)
{
var input = Console.ReadKey(false);
Console.WriteLine(input.KeyChar);
}
With that code each character will get duplicated (so you will get aabbccddee). Change the false to true in ReadKey to fix that.

Related

C# Wrong Value stored in variable

I am fairly new to programming so have some mercy ;)
I am trying to build a program that can solve equations and give gradient and so on in c#, so I can make it more complex gradually. Problem is, there appears to be a wrong value from my input when I tried to start building it.
Console: Given value for "a":
9 The Output: 57
My Code:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Input an linear Eqasion in the following Pattern -- a * x + b");
Console.Write("Given value for \"a\":");
decimal aValue;
aValue = Console.Read();
Console.Write(aValue);
}
}
}
Console.Read() returns an int, but not in the way you think. It returns the numeric value of the typed character, not the human-intuitive interpretation of a character that coincidentally happens to be a number. Consider for example what it would return if you type a letter, or any other non-numeric character.
And what is the numeric (decimal) value for the character '9'? 57 is.
It sounds like you want to read the line, not the character. For example:
string aValue;
aValue = Console.ReadLine();
Console.Write(aValue);
Remember that you'll need to press return to send the line to the application.
If you'll later need the value to be numeric, you'll still want to input the string but will want to parse it. For example:
string aValue;
aValue = Console.ReadLine();
if (decimal.TryParse(aValue, out decimal numericValue)
{
Console.Write(numericValue);
}
else
{
// The value could not be parsed as a decimal, handle this case as needed
}
Console.Read returns the character code entered on the command line in this scenario. The ASCII character code of 9 is 57. If you're wanting numeric input, you'd be better using Console.ReadLine with Decimal.Parse (or better yet, Decimal.TryParse)
It is also worth noting that Console.Read only returns one character at a time, meaning for any inputs past 1 digit you'll need special handling. I highly recommend using ReadLine and parsing the string over handling converting the character codes to the number they represent.

How to determine that a null character does not give an error in a sentence

** I wanted to check a sentence whether contains one null character between two words. I am new. So, there is not much of code samples for This problem. **
I used String.IsNullOrEmpty to determine the emptiness of the string. However, I did wrong.
Can you help me about that?
**Edit: I'm sorry for My mistake. This question needs an example. For example; I Write to the textbox "It is good" It determines null characters between "It" and "is" AND "is" and "good". So, it gives an error message. However, İf I Write one single character, it does not give me error message.
PS: This error message means a label. If it contains a null character, Red label shows itself. Else, Green label shows itself.**
Edit 2
Public Static bool IsAllLetters(string s)
{ foreach (char c in s)
{ if (!char.IsLetter(c) return false; return true; }
I determine whether the string contains Letter or not. If it contains a number character, it gives error.
Anyway, that explains why I used IsAllLetter function.
then I used This code samples.
Bool exp = IsAllLetters(explanation_text.Text);
İf (exp == false){ // wrong data }
Else { // correct data }
So, Which Code should I change? Or What Code should I add?
Your code formatting is a bit rough, but it looks like your foreach returns prematurely when the string has Length greater than 1
foreach (char c in s)
{ if (!char.IsLetter(c) return false; return true; }
The code above only ever checks the first character of a string. Instead, you want IsAllLetters to only return true if all characters have been scanned.
public static bool IsAllLetters(string s)
{
foreach (char c in s)
if (!char.IsLetter(c)) return false;
return true;
}

The Convert class and converting Console input C#

This question is more of a "Why can't I do this/What am I doing wrong" as I have managed to accomplish what the program should do, but it raised more questions around why certain things work the way they do.
For starters, the goal of this project is to capture a single character from the Console window (using Console.Read()/.ReadLine()), convert it to a string with the Convert class, and then write it to the Console window.
I've managed to get my project to have this functionality with the following code:
namespace ReadConvertWrite
{
class Program
{
static void Main(string[] args)
{
String input = Console.ReadLine();
try
{
Convert.ToInt32(input);
}
catch (Exception)
{
}
Console.WriteLine(input);
Console.ReadLine();
}
}
}
Given that this seems like a pointless exercise since the conversion is unnecessary I wanted to make it necessary by using the .Read() method instead of .ReadLine(). Which leads me to my question:
Why is it that .Read() always prints the hexadecimal value of the character inputted into the console despite the MSDN documentation making it sound like .Read() and .ReadLine() work the same way apart from reading a single character Vs a line, and beyond that why do none of the Convert class methods I've tried (.ToInt, .ToString, etc) work to actually give me output other than the hexadecimal values?
Here's what I've tried so far:
namespace ReadConvertWrite
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Convert.ToString(Console.Read()));
Console.ReadLine();
Console.ReadLine();
}
}
}
And:
namespace ReadConvertWrite
{
class Program
{
static void Main(string[] args)
{
var input = 0;
input = Console.Read();
String InputString = Convert.ToString(input);
Console.ReadLine();
Console.ReadLine();
}
}
}
Console.Read returns an integer representing a character. Console.ReadLine returns a string.
When you do Console.WriteLine(Console.ReadLine()), you're simply echoing your input. When you do Console.WriteLine(Convert.ToString(Console.Read())), you're taking the numeric value of the character and printing it as a number.
Convert.ToString(int) will not interpret the integer as a character - that would be rather ridiculous. Would you expect Convert.ToString(42) to print *? You need to cast the integer to a character instead:
Console.WriteLine((char)Console.Read());
Most likely, you don't want to use Console.Read anyway - it's a rather specific thing dealing with old-school CLI, rather than anything very useful for a typical console program, unless you need to stream lots of characters and want to avoid allocating huge strings unnecessarily.
Make sure to handle end-of-file correctly - Console.Read() will return -1 when the input stream ends, which is not a valid value for char.
If you hover your mouse over Read() it will show you it returns an int, not a string. Converting an 'int' to a string will just be a string representation of an int. To get a character from an int, cast it back to a char.
The cast to a char will convert the number back into its character representation.
Console.WriteLine((char)Console.Read());

Char tryParse not working as I thought?

I have some problem with a method that I have done in c#. I'm trying to stop user from entering anything else then y and n. It's almost working that I want, but user can still enter more than one sign, and then it doesn't work! How can I do to also check if char is more than one char? I thought the tryParse solved that? Thanks!
// Method to check if item is food or not
private void ReadIfFoodItem()
{
Console.Write("Enter if food item or not (y/n): ");
if (char.TryParse(Console.ReadLine(), out responseFoodItem))
{
if(Char.IsNumber(responseFoodItem))
{
Console.WriteLine(errorMessage);
ReadIfFoodItem();
}
else
{
// Set true or false to variable depending on the response
if ((responseFoodItem == 'y' || responseFoodItem == 'Y'))
{
foodItem = true;
selectedVATRate = 12; // Extra variable to store type of VAT
}
else if ((responseFoodItem == 'n' || responseFoodItem == 'N'))
{
foodItem = false;
selectedVATRate = 25; // Extra variable to store type of VAT
}
else
{
Console.WriteLine(errorMessage);
ReadIfFoodItem();
}
}
}
}
The following code "works" in that it produces the expected results.
char responseFoodItem;
Console.Write("Enter if food item or not (y/n): ");
if (char.TryParse(Console.ReadLine(), out responseFoodItem))
{
// Set true or false to variable depending on the response
if ((responseFoodItem == 'y' || responseFoodItem == 'Y'))
{
Console.WriteLine("foodItem = true");
}
else if ((responseFoodItem == 'n' || responseFoodItem == 'N'))
{
Console.WriteLine("foodItem = false");
}
else
{
Console.WriteLine("Unrecognised input");
}
}
else
{
Console.WriteLine("Invalid input");
}
However, has others have pointed out using ReadKey is a better solution if you want to limit the input to a single key. It also means that the user doesn't have to press the Return/Enter key for the input to be accepted.
char represents a single character, so How can I do to also check if char is more than one char? I thought the tryParse solved that? seems a bit nonsensical... TryParse will try and parse a single character from your input and will explicitly fail if the value is null or has a length > 1.
Instead of checking a character, just check the string, e.g.:
string line = Console.ReadLine();
switch (line.ToUpperInvariant())
{
case "Y":
// Do work for y/Y
break;
case "N":
// Do work for n/N
break;
default:
// Show error.
break;
}
char.TryParse simply tries to parse the string supplied as an argument, it does not limit the number of characters that you can input to the console using Console.ReadLine.
When the user inputs more than a single character, char.TryParse will fail because the string returned by Console.ReadLine doesn't contain a single character.
You should use Console.Read instead.
How can I do to also check if char is more than one char?
string line = Console.ReadLIne();
If(!string.IsNullOrEmpty(line) && line.Length > 1)
for reading a single char use Console.ReadChar() instead.
Console.ReadLine allows users to type a string of any length and press enter.
How can I do to also check if char is more than one char? I thought the tryParse solved that?
From the manual page:
Converts the value of the specified string to its equivalent Unicode character. A return code indicates whether the conversion succeeded or failed....The conversion fails if the s parameter is null or the length of s is not 1.
Have you tried using Console.ReadKey instead of ReadLine?
To check it the user has inserted more then one char you could check the string length instead of use Char.TryParse
......
private void ReadIfFoodItem()
{
string answer=string.empty;
Console.Write("Enter if food item or not (y/n): ");
answer=Console.ReadLine()
if (answer.lenght>=1))
{
//error
.......
}
...............
This answer should help you: How can I limit the number of characters for a console input? C#
The console does not limit the user input (well it does, but to 256 characters), nor does char.TryParse which doesn't do anything at all to limit the input length.
You can try using Console.ReadKey
It's just one keystroke for the user and you know there won't be more than one char.
Why not comparing to the input'ed string?
And why not simplifying the comparison?
using System.Linq;
private static string[] ValidAnswers = new string[]{ "y", "yes" };
// Method to check if item is food or not
private void ReadIfFoodItem() {
Console.Write("Enter if food item or not (y/n): ");
string ans = Console.ReadLine();
// Checks if the answer matches any of the valid ones, ignoring case.
if (PositiveAnswers.Any(a => string.Compare(a, ans, true) == 0)) {
foodItem = true;
selectedVATRate = 12; // Extra variable to store type of VAT
} else {
foodItem = false;
selectedVATRate = 25; // Extra variable to store type of VAT
}
}
Alternatively, as others said, you can use Console.ReadKey().
Use Console.ReadKey() to limit the amount of characters. To test whether you have a Y or an N then you can compare the ASCII codes or use a regular expression.

Reading two Characters in C#

I cannot read a second character with Console.Read() method. I mean I don't get any Prompt to read the second character from Keyboard. Any help please? Also, I understand that character is by default an int but we still need to convert it to char when reading from input, is it right? The code below reads the first char but terminates with the second.
public static void Main()
{
Console.WriteLine("The First Character?:");
char firstChar=Convert.ToChar(Console.Read());
Console.WriteLine("The Second Character?:");
char secondChar=Convert.ToChar(Console.Read());
}
Looks like Console.ReadKey() is what you actually want.
Please see Console.Read. Specifically, this part:
The Read method blocks its return while you type input characters; it terminates when you press the Enter key. Pressing Enter appends a platform-dependent line termination sequence to your input (for example, Windows appends a carriage return-linefeed sequence). Subsequent calls to the Read method retrieve your input one character at a time. After the final character is retrieved, Read blocks its return again and the cycle repeats.
Perhaps this code is closer to what you're looking for...
public static void Main()
{
Console.WriteLine("The First Character?:");
char firstChar = Convert.ToChar(Console.ReadKey().KeyChar);
Console.WriteLine();
Console.WriteLine("The Second Character?:");
char secondChar = Convert.ToChar(Console.ReadKey().KeyChar);
}
Your second Console.Read() is consuming the carriage return terminating the first read.
Console.ReadKey is a bit friendlier to use, since it doesn't require a terminating carriage return. If you want to continue using Console.Read, you might try consuming and discarding the carriage return before the second prompt, like:
public static void Main()
{
Console.WriteLine("The First Character?:");
char firstChar = Convert.ToChar(Console.Read());
Console.Read(); // consume carriage return
Console.WriteLine("The Second Character?:");
char secondChar = Convert.ToChar(Console.Read());
Console.WriteLine(secondChar);
}

Categories