My If- else statement only runs the else portion - c#

I am teaching myself c# with the help of a few books and I got curious so I tried building a small console app to get two numbers from user add them together and using an if else statement depending on the result print one of the messages but my code asks for the second number and prints the else statement and the press any key to continue all at the same time without getting my second number or doing the math
using System;
namespace helloworldwcond
{
class Program
{
public static void Main(string[] args)
{
int a;
int b;
int c;
Console.Write("Enter a Number: ");
a = Console.Read ();
Console.Write ("Enter another Number: ");
b = Console.Read ();
c = a + b;
if (c == 7) {
Console.WriteLine("Hello World!");
} else {
Console.Write("We Are DOOMED");
}
// TODO: Implement Functionality Here
Console.Write ("Press any key to continue . . . ");
Console.ReadKey (true);
}
}
}

The problem is the way you get your input. You should use Console.ReadLine() instead of Console.Read(). The correct code should be:
int a;
int b;
int c;
Console.Write("Enter a Number: ");
a = Int32.Parse(Console.ReadLine());
Console.Write("Enter another Number: ");
b = Int32.Parse(Console.ReadLine());
// The rest are the same
Why use Console.ReadLine() instead of Console.Read()?
Console.Read() return the ASCII code of the input character. For example, you enter 4 for a, then what you get is a = 52, not a = 4, because 52 is the ASCII code of character 4.
Console.Read() only read 1 character from the input stream. So, when you enter value for a, you type: 3 enter. At that time, your input stream has 2 characters: 3 and enter. Then, when you call Console.Read() for b, it will read the next character, which is enter, and go on. It's the reason for the behavior of your program.
In conclusion, you should use Console.ReadLine() to read a line, then parse it as you want.
To know more about the difference between that 2 functions, please read this post.

Console.Read returns the next character as an integer.
So a 0 is ASCII 48, so entering a 0 will return 48.
Use Convert.ToInt32() to convert a character to the integer value.
a = Convert.ToInt32(Console.Read());
Of course you may want to also add checking that the character typed is a number. And this will only work for 1 digit numbers.
Either way, probably want to do a Console.ReadLine() instead which will return a string of everything typed until they hit enter. Then convert the string to a number as int.Parse(string value)
Console.Write("Enter a Number: ");
string temp = Console.ReadLine();
a = Int32.Parse(temp); // Or could use
bool isThisANumber = Int32.TryParse(temp, a);

As answered by Mike above, Console.Read returns the ASCII value of the first character in the input. You could use Console.ReadLine instead and parse the string as an integer. Mike has suggested as well while I was posting this.
using System;
namespace helloworldwcond
{
class Program
{
public static void Main(string[] args)
{
int a;
int b;
int c;
Console.Write("Enter a Number: ");
a = int.Parse(Console.ReadLine());
Console.Write("Enter another Number: ");
b = int.Parse(Console.ReadLine());
c = a + b;
if (c == 7)
{
Console.WriteLine("Hello World!");
}
else
{
Console.Write("We Are DOOMED");
}
// TODO: Implement Functionality Here
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}

Console.Read returns the ascii value of the input given. For a quick and dirty solution try this:
int a;
int b;
int c;
Console.Write("Enter a Number: ");
a = Console.Read() - '0';
Console.Write("Enter another Number: ");
b = Console.Read() - '0';
c = a + b;
if (c == 7)
{
Console.WriteLine("Hello World!");
}
else
{
Console.Write("We Are DOOMED");
}

Related

Calculating product of numbers using do while

I'm new to coding and trying my best but I got stuck. Again.
So. I need to calculate the product of some random numbers using do while.
You type the numbers and when you type x, the loop needs to close showing the result. If you ONLY type x, it needs to show "1".
I can't manage to only show "1" when you type "x".
I have this:
int product = 1;
Console.WriteLine();
String input = Console.ReadLine();
do
{
int n = Convert.ToInt32(input);
product = product * n;
input = Console.ReadLine();
} while (!input.ToLower().Equals("x"));
Console.WriteLine(product);
Console.ReadLine();
for and while breaks in the start of the loops and do while break at the end, sometimes you have to break it the middle (here after the input was entered, if it's x) and before the accumulation.
The best way to manage this is an infinite loop for(;;) or while(true) and uses of break:
var product = 1;
for(;;)
{
var input = Console.ReadLine();
if (input is null || input.Equals("x", StringComparison.OrdinalIgnoreCase))
break;
product *= Convert.ToInt32(input);
}
Console.WriteLine(product);
Console.ReadLine();
Or you can try to make it fit (mostly double calls to ReadLine).
A for version that looks ugly:
var product = 1;
for (var input = Console.ReadLine(); input != "x"; input = Console.ReadLine())
{
product *= int.Parse(input);
}
Console.WriteLine(product);
Console.ReadLine();
A while version:
var product = 1;
var input = Console.ReadLine();
while (!input.ToLower().Equals("x"))
{
product *= Convert.ToInt32(input);
input = Console.ReadLine();
}
Console.WriteLine(product);
Console.ReadLine();
Another while version that avoid ReadLine at multiple places:
var product = 1;
string input;
// an affectation actually evaluate to the value affected
// avoid this since it's not easily readable (= and == mismatch)
while ((input = Console.ReadLine()) != "x")
{
product *= Convert.ToInt32(input);
}
Console.WriteLine(product);
Console.ReadLine();
A do while version:
I add it because it's in the question title, otherwise I didn't consider it a good solution.
Based on yassinMi answer.
var product = 1;
var input = "1";
do
{
product *= int.Parse(input);
input = Console.ReadLine();
} while (input != "x");
Console.WriteLine(product);
Console.ReadLine();
A Linq version:
var product = Enumerable.Range(0, int.MaxValue) // many elements
.Select(_ => Console.ReadLine()) // discard them and take the console input
.TakeWhile(s => s != "x") // stop on 'x'
.Select(int.Parse) // parse to int
.Aggregate(1, (a, b) => a * b); // accumulate from 1 and by making the product
Console.WriteLine(product);
Console.ReadLine();
a simple fix: change the line
String input = Console.ReadLine();
to
String input = "1";
otherwise you would use the while loop, or add extra if statement..
Welcome to C#!
Your issue is most likely due to an error while converting a value. You are trying to convert "x" to int, but "x" is a letter, which cannot be converted to a number.
Cause of the issue
The problem of this program is that you are trying to convert a letter to a number. This is not possible in real life, and less possible in programming! A computer is not able to convert a number to a letter, unless you are explaining to it how, or if your handle the error properly.
The following line:
int n = Convert.ToInt32(input);
...Does not check for what has been entered. Convert.ToInt32() will throw an exception if the string? (From Console.ReadLine()) could not be converted.
The fix
To fix this issue, you need to handle the input of the user. Literally anything is accepted by Console.ReadLine() but you want a value that can be converted to a int.
The int type has a built-in function to convert a value without throwing an exception if it couldn't be converted, instead, it returns a bool (Either true or false).
So the following changes need to be brought to your program:
int product = 1;
string ? input;
do {
input = Console.ReadLine();
// Try to parse to integer, if it couldn't be parsed to integer, continue.
if (!int.TryParse(input, out int n)) {
continue;
}
product = product * n;
} while (!input.Equals("x", StringComparison.InvariantCultureIgnoreCase));
Console.WriteLine(product);
// End of the program
Console.WriteLine("Press any key to quit the program.");
Console.ReadKey();
Trying to parse a string to an integer
The method int.TryParse(string? input, out int output); allows you to try to convert a string to a int.
If the method fails, instead of throwing an Exception, it will returns false.
Getting the output value
The output value can be obtained from out int output, out allows you to output a value from a function.
The logic would be that if int.TryParse(...) returns true, the value can be used, otherwise you can continue.
The continue statement tells your loop that the current loop should be skipped and goes to the next one (= At the beginning of your loop).
Other changes
I've brought to your program some changes to make it more readable and easier to edit.
Firstly, you'd want to use Equals(input, StringComparison.InvariantCultureIgnoreCase) instead of ToLowerCase(), the result is the same and it is cleaner! 🙂
Also, you can directly ask the input within your while loop since this will be repeated each time, you just need to position it correctly so the value can be verified.
Final program
ConsoleKeyInfo continueProgram = new ConsoleKeyInfo();
ConsoleKeyInfo continueInput = new ConsoleKeyInfo();
List<int> products = new List<int>();
do
{
Console.Clear();
do
{
Console.Write("\nPlease enter new number . . . ");
if (int.TryParse(Console.ReadLine(), out int result))
{
products.Add(result);
Console.WriteLine("\nNew Product Added!");
}
else
{
Console.WriteLine("\nYou have entered a value that is not an integer!\n");
}
Console.Write("\nDo you want to enter an other value (press Y) or any key to exit . . . ");
continueInput = Console.ReadKey();
Console.WriteLine();
}
while (continueInput.Key == ConsoleKey.Y);
Console.WriteLine();
foreach (var item in products)
{
Console.WriteLine(item.ToString());
}
Console.ReadLine();
Console.Write("\n\nPress 'Y' to continue or any other key to exit! . . . ");
continueProgram = Console.ReadKey();
} while (continueProgram.Key == ConsoleKey.Y);
The problem is that Console.ReadLine() gets called twice before checking for x. The first input gets eaten up.
What you need to do is inside the loop ask and process the input, and exit the loop when the condition is met.
One way of doing this is by keeping a boolean value called done indicating when to exit the loop'
static void Main(string[] args)
{
int product = 1;
bool done = false;
do
{
Console.WriteLine("Enter number or 'x' to calculate result.");
string input = Console.ReadLine();
done = input.ToLower() == "x";
if (int.TryParse(input, out int value))
{
product *= value;
}
else
{
Console.WriteLine("Input ignored.");
}
} while (!done);
Console.WriteLine($"The product is {product}");
}
Another more succinct way is to use the break; statement
static void Main(string[] args)
{
int product = 1;
do
{
Console.WriteLine("Enter number or 'x' to calculate result.");
string input = Console.ReadLine();
if (input.ToLower() == "x")
{
// this exits the loop
break;
}
if (int.TryParse(input, out int value))
{
product *= value;
}
else
{
Console.WriteLine("Input ignored.");
}
} while (true);
Console.WriteLine($"The product is {product}");
}
Also, it is recommended to use int.TryParse(string, out integer) for better handling weird user inputs instead of Convert.ToInt32(). See the pattern above on how it is used.

How to press enter for a menu without the enter being used for the next operation

So, I am learning C#, and to practice, I have been trying to make a math solver, so the way I did it, is 1- I present the math question, 2- I receive user-input of the solution, 3- I compare the user's answer to my answer using an if statement, now, I am trying to add a console menu to add different divisions (multiplication/division/sub./add.), i have successfully added the menu, however I am not able to move onto inputting the numbers, the error I get is http://prntscr.com/ohru2i, how can I fix it?
I have tried putting Console.clear(), I have also tried to use break;, but none of them worked
using Figgle;
using System;
using System.Threading;
public class MainClass
{
public static void Main()
{
Console.Title = $"The Math Solver | Correct = 0 | Wrong = 0";
char choice;
for (; ; )
{
do
{
Console.WriteLine("Choose Method:");
Console.WriteLine(" 1. Multiplication");
Console.WriteLine(" 2. Division");
Console.WriteLine(" 3. Addition");
Console.WriteLine(" 4. Subtraction");
Console.WriteLine(" 5. Find the Remainder");
Console.WriteLine("Press Q to Exit ");
do
{
choice = (char)Console.Read();
} while (choice == '\n' | choice == '\r');
} while (choice < '1' | choice > '5' & choice != 'q');
if (choice == 'q') break;
Console.WriteLine("\n");
Console.Clear();
switch (choice)
{
case '1':
{
Console.WriteLine(
FiggleFonts.Standard.Render("Multiplication"));
int milliseconds2 = 2000;
Thread.Sleep(milliseconds2);
int correctAnswers = 0;
int WrongAnswers = 0;
int Number1;
int Number2;
int myInt2;
while (true)
{
Console.WriteLine("Write the first number to multiply");
Number1 = int.Parse(Console.ReadLine());
Console.WriteLine("Write the second number to multiply");
Number2 = int.Parse(Console.ReadLine());
Console.WriteLine($"Write the answer of {Number1} * {Number2}");
myInt2 = int.Parse(Console.ReadLine());
if (myInt2 == Number1 * Number2)
{
Console.WriteLine(
FiggleFonts.Standard.Render("Correct!"));
correctAnswers++;
Console.Title = $"The Math Solver | Correct = {correctAnswers} | Wrong = {WrongAnswers}";
}
else
{
Console.WriteLine(
FiggleFonts.Standard.Render("Wrong"));
WrongAnswers++;
Console.Title = $"The Math Solver | Correct = {correctAnswers} | Wrong = {WrongAnswers}";
}
int milliseconds3 = 2000;
Thread.Sleep(milliseconds3);
Console.Clear();
}
}
}
}
}
The error message I get is http://prntscr.com/ohru2i
You're getting the error when converting a number to a string because console.Read() consumes the first character from the standard input, but leaves the line break from the user hitting enter. Therefore, the next time you go to read a line from the console, you just get a blank line, which is not a valid string for number conversion.
Solution is to use Console.ReadLine() and either look at the first character by indexing the string, or replace choice character constants with string constants.

how do I write in the same line that the user wrote?

The user enters a numbers and the program should make a sideways graph by writing "-" * the amount of digits in the number, but it writes the "-" a line under the user input
Current output:
Expected output:
static void Main(string[] args)
{
int num1, num2;
Console.WriteLine("how many numbers will you want to enter?");
num1 = int.Parse(Console.ReadLine());
Console.WriteLine("Enter " + num1 + " numbers");
for(; num1 > 0; num1--)
{
num2 = int.Parse(Console.ReadLine());
Hi(num2);
}
}
static void Hi(int num)
{
while(num != 0)
{
num /= 10;
Console.Write("-");
}
Console.WriteLine()
}
You can get and set the cursor position in the console, so if you remember which line it is on before the user presses enter for the number entry, you can put the cursor back on that line.
Also, to print a number of dashes of the length of the input, it is not necessary for the input to be digits (or you would have checked for that).
Something like this should be suitable:
static void Main(string[] args)
{
Console.Write("How many numbers will you want to enter? ");
int num1 = int.Parse(Console.ReadLine());
Console.WriteLine("Enter " + num1 + " numbers");
for (; num1 > 0; num1--)
{
int currentLine = Console.CursorTop;
string num2 = Console.ReadLine();
Console.SetCursorPosition(20, currentLine);
Console.WriteLine(new string('-', num2.Length));
}
Console.WriteLine("\r\n(Press enter to leave program.)");
Console.ReadLine();
}
Sample output:
How many numbers will you want to enter? 4
Enter 4 numbers
1 -
435 ---
What happens long wi-----------------------
(Press enter to leave program.)
Use a method like the following:
public string getKeyBuffer()
{
string buffer = "";
do
{
var charIn = Console.ReadKey(true);
if (charIn.Key == ConsoleKey.Enter) break;
buffer += charIn.KeyChar;
Console.Write(charIn.KeyChar);
} while (true);
return buffer;
}
This will echo each key pressed and then return all the keys pressed once the user presses the enter key without echoing the enter key.
The best solution would be to write to something other than the console, where you would have absolute control over what is displayed and where.
Another solution would be to format a string in your code, then clear the console and write the entire thing each time.
Another solution would be to keep track of where you are and move the console cursor using Console.SetCursorPosition. However, this is rarely a satisfying solution given the existence of nicer output alternatives.
You can move the cursor up one line with Console.CursorTop--;, avoiding the necessity of keeping track of which line you are on.

Unexpected result at summing numbers using a while loops in console application

I am trying to make a program to sum numbers until the user enter OK.
The program make the sum, but return a bad result.
i'm not sure where is my error...
int sum = 0;
Console.WriteLine("Enter number:");
int num = Convert.ToInt32(Console.ReadLine());
while (Console.ReadLine() != "OK")
{
sum += num;
}
Console.WriteLine(sum);
you don't keep the number the use enter in the while loop.
you need to input the readline to a variable.
var num = Console.Readline();
sum += num; //parse first
Inside your while loop you need to update num:
int num = Convert.ToInt32(Console.ReadLine());
while (Console.ReadLine() != "OK")
{
num = Int32.Parse(Console.ReadLine());
sum += num;
}
Also just as a note, if you need your program to be a little safer, you can you use the following:
int num;
if(Int32.TryParse(Console.ReadLine(), out num)) {
//do something..
}
else {
//do something else.. like end program, throw exception etc.
}
Int32.TryParse:
Converts the string representation of a number to its 32-bit signed
integer equivalent. A return value indicates whether the conversion
succeeded
This way you can do something in the instance that the input string was not a valid conversion. Example: if someone input cat, which can not be converted to an int, it would crash your program without the TryParse.
You need to input the number once per iteration, and store it each time. So each value retrieved from Console.ReadLine() needs to be captured in an assignment statement, then converted to a number if it is not "OK".
I think you're after this:
int sum = 0;
string input;
Console.WriteLine("Enter number: ");
while ((input = Console.ReadLine()) != "OK")
{
int inputNum = Convert.ToInt32(input);
sum += num;
Console.WriteLine("Enter number: ");
}
The statement (input = Console.ReadLine() assigns the user input to the input variable, then the assignment statement returns the value of input. Then that value is compared against OK.
An alternative way to get input, then check it is:
Console.WriteLine("Enter number: ");
input = Console.ReadLine()
while (input != "OK")
{
...
Console.WriteLine("Enter number: ");
input = Console.ReadLine()
}
int sum = 0;
Console.WriteLine("Enter number:");
int num = int.Parse(Console.ReadLine());
while (sum< num)
{
sum++;
}
Console.WriteLine(sum);

How do I ask the user for input in C#

I am switching from Python to C# and I am having trouble with the ReadLine() function. If I want to ask a user for input Python I did it like this:
x = int(input("Type any number: "))
In C# this becomes:
int x = Int32.Parse (Console.ReadLine());
But if I type this I get an error:
int x = Int32.Parse (Console.ReadLine("Type any number: "));
How do I ask the user to type something in C#?
You should change this:
int x = Int32.Parse (Console.ReadLine("Type any number: "));
to this:
Console.WriteLine("Type any number: "); // or Console.Write("Type any number: "); to enter number in the same line
int x = Int32.Parse(Console.ReadLine());
But if you enter some letter(or another symbol that cannot be parsed to int) you will get an Exception. To check if entered value is correct:
(Better option):
Console.WriteLine("Type any number: ");
int x;
if (int.TryParse(Console.ReadLine(), out x))
{
//correct input
}
else
{
//wrong input
}
Starting from C# 7 you can use inline variable declaration (out variables):
Console.WriteLine("Type any number: ");
if (int.TryParse(Console.ReadLine(), out var x)) // or out int x
{
//correct input
}
else
{
//wrong input
}
Console.WriteLine("Type any number");
string input = Console.ReadLine();
int x;
if (int.TryParse(input, out x))
{
//do your stuff here
}
else
{
Console.WriteLine("You didn't enter number");
}
Console.WriteLine("Type any number: ");
string str = Console.ReadLine();
Type a = Type.Parse(str);
where Type is Data Type you want to cast user input to.
I suggest reading few books on C# fundaments before turning to forums.
To be more generic I would suggest you to make an additional object ( because you cannot extend static objects in C# ) to behave like you've specified.
public static class ConsoleEx
{
public static T ReadLine<T>(string message)
{
Console.WriteLine(message);
string input = Console.ReadLine();
return (T)Convert.ChangeType(input, typeof(T));
}
}
Of course you this code is not error free because it does not contains any constraints about the output type but still It will cast into some types without any problems.
For example. Using this code :
static void Main()
{
int result = ConsoleEx.ReadLine<int>("Type any number: ");
Console.WriteLine(result);
}
>>> Type any number:
<<< 1337
>>> 1337
Check this online
try this
Console.WriteLine("Type any number: ");
int x = Int32.Parse (Console.ReadLine());

Categories