C# Wrong Value stored in variable - c#

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.

Related

Why is my code outputting strings multiple times in my if statement?

My code outputs the same string multiple times. For example, typing in 40 results in "Nope! Your answer is too high. Try again." twice, and it displays "your answer is too low" twice.
while (numberguess != 40.5)
{
numberguess = Console.Read();
if (numberguess < 40.5)
{
Console.WriteLine("Nope! Your answer is too low. Try again.");
}
else if (numberguess > 40.5)
{
Console.WriteLine("Nope! Your answer is too high. Try again.");
}
else if (numberguess == 40.5)
{
Console.WriteLine("Correct! Wow, I didn't really think you would figure it out!");
break;
}
}
I expect only one string to show up when typing in a number, and I want it to correspond to whether it is lower or higher than a particular number.
There are several problems with this single line:
numberguess = Console.Read();
First this returns an int, so it will never return 40.5. Also this reads one character at a time, including the ones input by the enter key, so when you type 40 and press Enter it reads '4', then '0' then '\r' and finally '\n' (converting those chars to int). That's why it displays four messages.
Instead you have to read everything typed before the Enter with Console.ReadLine() and then convert this (string) to a double. So in the end you have to do this:
numberguess = double.Parse(Console.ReadLine());
Console.Read() reads a single character as an int. If you're trying to get what the user typed before they hit enter, read the current line, and then parse an integer from it.
int.Parse(Console.ReadLine());

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());

Incorrect value when converting toString("G29")

I have code to remove trailing zeros from a value before presenting it to the UI, however I have found that in some cases, instead of removing the zeros it alters the value.
eg: 123.400000000000000000 becomes 123.40000000000001
the code I am using is:
string value = "123.400000000000000000";
value = double.Parse(value).ToString("G29");
Does anyone know why this is happening, and how I can alter my code so it shows '123.4' instead.
It's because you're turning it into a double and, as everyone who's spent time dealing with floating point values will know, double precision values are not infinite precision values. The value selected is as close as it can get to what you provide but that's not always exactly what you want.
If you have a numeric-style string that you want to strip trailing zeros from, why don't you just strip the trailing zeros from it, with something like:
if (s.Contains(".")) {
Regex regex = new Regex("\\.?0*$");
s = regex.Replace(s,"");
}
The check for a . character is to ensure you don't strip trailing zeros off a number like 1000. Once you know there's a decimal point in there, zeros (and the decimal point itself if it's _all zeros after that) can be stripped off the end with impunity. You can see it in action in the following complete console program:
using System;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static string StripZ(string s)
{
if (s.Contains("."))
{
Regex regex = new Regex("\\.?0*$");
s = regex.Replace(s, "");
}
return s;
}
static void Main(string[] args)
{
Console.WriteLine(StripZ("123.400"));
Console.WriteLine(StripZ("3.0"));
Console.WriteLine(StripZ("7."));
Console.WriteLine(StripZ("1000"));
Console.ReadLine();
}
}
}
The output of that program is:
123.4
3
7
1000
The problem is that 123.4 is not exactly representable in a binary floating point data type. The closest double precision value is:
123.40000 00000 00005 68434 18860 80801 48696 89941 40625
The ToString method is rounding that to
123.40000 00000 0001
You should use a decimal data type instead of a binary data type. For instance:
string value = "123.400000000000000000";
value = decimal.Parse(value).ToString("G29");
However, if you are really starting with a string, and just wish to trim trailing zeros then it would perhaps be more prudent to do that using text processing.

Using PromptforLetter and DisplayLetter in C#

Below is a homeowrk assignment I've been working on.
I need to create a class called FormattedOutput in a file called FormattedOutput.cs. That class will have the following methods:
char PromptforLetter(void) - this method will return a value
void DisplayLetter(char letter) - this method will accept a value to display
Main should be in a file named mainModule.cs
Main will PromptforLetter for each character in your name and store each character into a char data type.
Then DisplayLetter(letter1) should display each letter as:
the actual letter
the decimal value of the key
the hexadecimal value of the key
the octal value of the key
the binary value of the key
Information should be displayed first...
Then prompts for each letter of your name.
Then a Table showing each value
Char Decimal Hex Octal Binary
Here is the horrible mess I have at this time
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class formattedOutput
{
char PromptforLetter(string prompt)
{
string value;
char achar;
Console.WriteLine("A", prompt);
Console.WriteLine("L", prompt);
Console.WriteLine("M", prompt);
Console.WriteLine("A", prompt);
Console.Read();
value = Console.ReadLine();
achar=Convert.ToChar(value.Substring(0,1));
return achar;
}
void DisplayLetter (char letter)
{
Console.WriteLine("A");
Console.Read();
I'm fairly uncertain of what you're going for, and it might help to clear up your introduction to the problem (or instance, we don't need to know filenames and such, just give the relevant details). It also seems like you're asking quite a few questions, so I'm going to focus on what I think you actually mean to ask.
The impression I'm getting is that you are to write a console application in C#, with a method to read a single character from user-input, then another one to echo it back to them using several number formats.
If that is, in fact, the case, you probably want something like this:
public char PromptforLetter(string prompt)
{
Console.Write(prompt + " "); // This prints out the prompt with a space, and no
// following line break
// Now you have a choice. Should you take the first key that is pressed, or
// should the user have to press enter?
// Option 1:
char ret = Console.ReadKey().KeyChar;
Console.WriteLine(); // Not necessary, but it improves user experience
return ret;
// Option 2:
return Console.ReadLine()[0]; // take the first indexed character from the
// string entered by the user. Strings have
// integer-indexers, so you can access single them
// characters in kind of like you would if they were
// a string array.
}
Printing the character is a bit simpler:
public void DisplayLetter(char val)
{
Console.Write("Char: {0}", val);
Console.Write("Decimal: {0}", (int)val);
Console.Write("Hex: {0:X}", (int)val);
Console.Write("Octal: {0}", Convert.ToString((int)val, 8));
Console.Write("Binary: {0}", Convert.ToString((int)val, 2));
}
Beyond that, it's mostly just up to you and what the instructor is looking for, specifically.

What does Int32.Parse do exactly?

I am just beginning to learn C#. I am reading a book and one of the examples is this:
using System;
public class Example
{
public static void Main()
{
string myInput;
int myInt;
Console.Write("Please enter a number: ");
myInput = Console.ReadLine();
myInt = Int32.Parse(myInput);
Console.WriteLine(myInt);
Console.ReadLine();
}
}
When i run that and enter say 'five' and hit return, i get 'input string not in correct format' error. The thing i don't understand is, i converted the string myInput to a number didn't i? Microsoft says that In32.Parse 'Converts the string representation of a number to its 32-bit signed integer equivalent.' So how come it doesn't work when i type the word five? It should be converted to an integer shouldn't it... confused. Thanks for advice.
'five' is not a number. It's a 4-character string with no digits in it. What parse32 is looking for is a STRING that contains numeric digit characters. You have to feed it "5" instead.
The string representation that Int32.Parse expects is a sequence of decimal digits (base 10), such as "2011". It doesn't accept natural language.
What is does is essentially this:
return 1000 * ('2' - '0')
+ 100 * ('0' - '0')
+ 10 * ('1' - '0')
+ 1 * ('1' - '0');
You can customize Int32.Parse slightly by passing different NumberStyles. For example, NumberStyles.AllowLeadingWhite allows leading white-space in the input string: " 2011".
The words representing a number aren't converted; it converts the characters that represent numbers into actual numbers.
"5" in a string is stored in memory as the ASCII (or unicode) character representation of a 5. The ASCII for a 5 is 0x35 (hex) or 53 (decimal). An integer with the value '5' is stored in memory as an actual 5, i.e. 0101 binary.

Categories