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.
Related
I am a beginner in c# and I want to create a simple calculator.
I have written all the code and it is not showing any errors, however, it is not showing it correctly.
This is all the code I am using:
using System;
namespace C_
{
class Program
{
static void Main(string[] args)
{
Console.Title = "Calculator";
float num1;
float num2;
float resultSum;
float resultSub;
float resultProd;
float resultDiv;
Console.Write("Enter your first number ");
num1 = Convert.ToInt32(Console.Read());
num2 = Convert.ToInt32(Console.Read());
resultSum = num1 + num2;
Console.Write("The sum is " + resultSum);
resultSub = num1 - num2;
Console.Write("The differnce is " + resultSub);
resultProd = num1 * num2;
Console.Write("The product is " + resultProd);
resultDiv = num1 / num2;
Console.Write("The quotient is " + resultDiv);
Console.ReadKey();
}
}
}
When I run this without debugging,
the console shows this:
https://learn.microsoft.com/en-us/dotnet/api/system.console.writeline?view=netcore-3.1
If you replace Console.Write... with Console.WriteLine..., it will add line breaks to the ends of your print statements, so your output should look like:
The sum is 63
The difference is 37
...
Not sure if I would use float for the type. Especially since you are converting to int32. I have put some different techniques into your program. Since you are just learning these are good things to know. I have provided explanations in the comments of the code.
static void Main(string[] args)
{
Console.Title = "Calculator";
// No need to put the type multiple times
// Just use a comma to separate the names
int num1, num2, resultSum, resultSub, resultProd, resultDiv;
Console.WriteLine("Enter your first number:");
// This is just a label
Num1Entry:
try
{
num1 = Convert.ToInt32(Console.ReadLine());
}
// This exception is for when you don't get a number from the user. i.e. num1 = a
catch (FormatException)
{
Console.WriteLine("Not a number. Please enter a valid number.");
// This will jump your program back to the beginning of the try-catch so you can enter a valid number for num1
goto Num1Entry;
}
// This exception is for when the number is out of range for the data type. i.e. num1 = 2147483648 is too big for an int data type.
catch (OverflowException)
{
Console.WriteLine("Invalid number. Please enter a valid number.");
// This will jump your program back to the beginning of the try-catch so you can enter a valid number for num1
goto Num1Entry;
}
Console.WriteLine("Enter your second number:");
// This is just a label
Num2Entry:
try
{
num2 = Convert.ToInt32(Console.ReadLine());
}
// This exception is for when you don't get a number from the user. i.e. num2 = a
catch (FormatException)
{
Console.WriteLine("Not a number. Please enter a valid number.");
// This will jump your program back to the beginning of the try-catch so you can enter a valid number for num2
goto Num2Entry;
}
// This exception is for when the number is out of range for the data type. i.e. num2 = 2147483648 is too big for an int data type.
catch (OverflowException)
{
Console.WriteLine("Invalid number. Please enter a valid number.");
// This will jump your program back to the beginning of the try-catch so you can enter a valid number for num2
goto Num2Entry;
}
resultSum = num1 + num2;
Console.WriteLine("The sum is " + resultSum);
resultSub = num1 - num2;
Console.WriteLine("The differnce is " + resultSub);
resultProd = num1 * num2;
Console.WriteLine("The product is " + resultProd);
// if num2 = 0 you will get an exception.
// Use a try-catch to keep your program from failing.
try
{
resultDiv = num1 / num2;
Console.WriteLine("The quotient is " + resultDiv);
}
catch (DivideByZeroException)
{
Console.WriteLine("You cannot divide by 0");
}
Console.ReadKey();
}
Your code uses the consolekey values, not the numeric value that you entered. The consolekey for 2 is 50. The consolekey for return is 13.
First days with C# and already stuck. My question is how to count all the answers that a user gave trying to find out what the random number is? And then put-it in the las sentence withe the right answer. That's how the "quiz" looks like:
public static void Main(string[] args)
{
Console.WriteLine("The secret number\n");
Random randomerare = new Random();
int slump_tal = randomerare.Next(1, 101);
Console.WriteLine("Write your number and we'll see where it lands:\n");
string user_nr = Console.ReadLine();
int tal = Convert.ToInt32(user_nr);
Console.WriteLine();
while (tal > slump_tal)
{
Console.WriteLine("Wrong! Your number is too big!\n");
user_nr = Console.ReadLine();
tal = Convert.ToInt32(user_nr);
}
while (tal < slump_tal)
{
Console.WriteLine("Wrong Your number is too low!\n");
user_nr = Console.ReadLine();
tal = Convert.ToInt32(user_nr);
}
while (tal == slump_tal)
{
Console.WriteLine("Bravo! That's the correct number\n");
break;
}
Console.WriteLine("The secret number was: {0}\n\nPush the button to finish", slump_tal);
Console.ReadKey(true);
}
There are 2 steps in your code. And you mixed them up.
Step 1: do a while loop to keep getting input from user.
Step 2: inside each loop, you need to validate the input against the number.
It should be 1 big while() loop with 3 if (). Let me know if you need example code.
I would do it like this:
1. Get a number
2. While the user is not hitting the right number:
2.1 let the user know if the number was too big or too small
2.2 ask for another number
2.3 count number-of-attems + 1
3. If the user arrived here, it means it has the number right, print number-of-attems
In code, this could look like this:
public static void Main(string[] args)
{
Console.WriteLine("The secret number\n");
Random randomerare = new Random();
int slump_tal = randomerare.Next(1, 101);
Console.WriteLine("Write your number and we'll see where it lands:\n");
Console.WriteLine();
int user_nr = Convert.ToInt32(Console.ReadLine());
// Here you can store the attempts
int attempts = 1;
// While the user provides the wrong answer, we iterate
while(slump_tal != user_nr)
{
// We add 1 to the counter
attempts++;
if (slump_tal > slump_tal)
{
Console.WriteLine("Wrong Your number is too low!\n");
}
else
{
Console.WriteLine("Wrong! Your number is too big!\n");
}
user_nr = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine($"Bravo! That's the correct number. you did it in {attempts} attemps");
Console.WriteLine("The secret number was: {0}\n\nPush the button to finish", slump_tal);
Console.ReadKey(true);
}
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.
When the input's type is not an integer, the program should fail. However, there are two problems:
After a letter is typed and I get the "not valid" response, then if the next input is a number, it won't accept it and says "not valid".
How can I make it so when a wrong number is inputted, it stays on the same row and just clears the previous input from the screen (and allows for a retry from the same position)?
static void Main(string[] args)
{
int firstNum;
int Operation = 1;
switch (Operation)
{
case 1:
Console.SetCursorPosition(0, 0);
Console.Write("Write a number: ");
firstNum = ReadInteger("");
Console.ReadKey();
break;
}
}
private static int ReadInteger(string title)
{
while (true)
{
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
string input = Console.ReadLine();
if (int.TryParse(input, out int result))
return result;
Console.WriteLine("Sorry, not a valid integer value; please, try again.");
Console.ReadKey();
}
}
Ad 1)
Because you have Console.ReadKey at the end of ReadInteger which will be executed as well. So if you hit Console.ReadLine at the line string input = Console.ReadLine(); and enter something that is not a number, int.TryParse will return false. This leads to the error message and the execution of Console.ReadKey. So you should first of all get rid of that Console.ReadKey there.
Ad 2)
You are setting the cursor position before the call of ReadInteger but not within ReadInteger. So if someone enters a text, the end of the input is typically done by pressing enter. You then write a line (with Console.WriteLine). So if you want to have the cursor at the same position, you will have to reset it's position within the loop which is within the ReadInteger method.
How about something like this:
public static int ReadInt(string prompt)
{
Console.Clear();
var length = prompt.Length + 2; //2 is for a colon and a space
var position = length;
Console.Write($"{prompt}: ");
string buffer = String.Empty;
int returnNum = 0;
while (true)
{
Console.SetCursorPosition(position, 0);
var charRead = Console.ReadKey();
if(charRead.KeyChar == '\r')
{
return returnNum;
}
if (!int.TryParse(buffer + charRead.KeyChar, out returnNum))
{
Console.SetCursorPosition(position, 0);
Console.WriteLine(" "); //overwrite
Console.SetCursorPosition(0, 1);
Console.Write("Error: enter only digits");
continue;
}
else
{
buffer += charRead.KeyChar;
++position;
//overwrite any error
Console.SetCursorPosition(0, 1);
Console.Write(" ");
}
}
}
It's not perfect. It doesn't handle typing in too many digits. It doesn't handle backspace. It clears the console to establish position (it doesn't look like you can read the console position, and I'm too lazy to keep track of things).
If you do handle backspace, make sure you don't let users backup too much. It's been years (um, no, decades) since I've done low level console management, but I can remember doing this in CP/M in the early 80s - if you backed up to far, the OS died (which would be a very result in Windows :-) ).
So I have this very simple program that I have created that gets the user input and then pass the values to the method named average. Everything is perfectly fine, however, something crossed my mind like "What if the user only enters two numbers or an array of numbers?". I know that I have to use array as a parameter, but somehow I am not sure how to accomplish what i want to do. Do you guys have any tips on how I can achieve what i am trying to do? My code is here:
using System;
namespace Averages
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter number(s): ");
double num1 = Convert.ToInt32(Console.ReadLine());
double num2 = Convert.ToInt32(Console.ReadLine());
double num3 = Convert.ToInt32(Console.ReadLine());
average(num1, num2, num3);
Console.ReadKey();
}
static void average(double num1, double num2, double num3)
{
double avg = (num1 + num2 + num3) / 3;
Console.WriteLine("You have entered: " + num1 + ", " + num2 + ", " + num3);
Console.WriteLine("The average is: " + avg);
}
}
}
I would appreciate any help. Thank you!
you can ask user for input of comma delimited numbers. Or, you can repeat input until user enters something like 0. I that case, you can change your program into this:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Averages
{
class Program
{
static void Main(string[] args)
{
//list to hold your numbers, way more flexible than array
List<double> enteredNubers = new List<double>();
//message user
Console.WriteLine("Enter number(s) or 0 to end: ");
//run this block of code indefinitely
while (true)
{
//take user input
string userinput = Console.ReadLine().Trim();
//if user enters 0, exit this loop
if (userinput == "0")
break;
double num;
//try to convert text to number
if (double.TryParse(userinput, out num))
{
//if it is successful, add number to list
enteredNubers.Add(num);
}
else //else message user with error
Console.WriteLine("Wrong input. Please enter number or 0 to end");
}
//when loop is exited (when user entered 0), call method that calculates average
Average(enteredNubers);
Console.ReadKey();
}
static void Average(List<double> numbers)
{
double sum = 0;
//go through list and add each number to sum
foreach (double num in numbers)
{
sum += num;
}
//or, you can sum it using linq like this:
//sum = numbers.Sum();
//or you can even calculate average by calling Average method on list, like numbers. Average();
//show message - all the entered numbers, separated by comma
Console.WriteLine("You have entered: " + string.Join(", ", numbers.ToArray()));
//write average
Console.WriteLine("The average is: " + sum/numbers.Count);
}
}
}
Let's solve the problem step by step. First we want to add a single double:
private static bool ReadDouble(out double value) {
value = 0.0;
while (true) {
Console.WriteLine("Enter number or X to exit:");
string input = Console.ReadLine().Trim();
if (input == "X" || input == "x")
return false;
else if (double.TryParse(input, out value))
return true;
Console.Write("Syntax error, please, try again.");
}
}
Now we are ready to read arbitrary number of values. Since we don't know the number, List<double> is a better choice than double[]
using System.Collections.Generic;
...
private static List<double> ReadDoubles() {
List<double> result = new List<double>();
while (ReadDouble(out var value))
result.Add(value);
return result;
}
Finally, we want to compute average
static void Main(string[] args) {
List<double> list = ReadDoubles();
if (list.Count <= 0)
Console.WriteLine("Empty list: no average");
else {
double sum = 0.0;
foreach (double item in list)
sum += item;
double avg = sum / list.Count;
Console.Write("The average is: " + avg);
}
}
However, you can do it in just few lines via Linq:
using System.Collections.Generic;
using System.Collections.Linq;
...
static void Main(string[] args) {
Console.WriteLine("Enter numbers separated by spaces, e.g. 1 2 3 15");
double avg = Console
.ReadLine()
.Split(new char[] { ' '}, StringSplitOptions.RemoveEmptyEntries)
.Select(item => double.Parse(item))
.Average();
Console.Write($"The average is: {avg}");
}
Here Update your methods Accordingly
static void Main(string[] args)
{
Console.WriteLine("Type Exit to stop the program... \nEnter number");
List<double> doubleList = new List<double>();
string input = Console.ReadLine();
double d;
while(!input.Equals("Exit"))
{
if(String.IsNullOrEmpty(input) || !Double.TryParse(input,out d))
{
break;
}
doubleList.Add(d);
input = Console.ReadLine();
}
average(doubleList);
Console.ReadKey();
}
static void average(List<double> doubleData)
{
double total = 0;
foreach (double number in doubleData)
{
total += number;
}
Console.WriteLine("Average = " + total/doubleData.Count);
}
Something like the following should meet your needs:
string stopLine = "STOP";
List<double> lines = new List<double>();
string line;
while ((line = Console.ReadLine()) != stopLine) {
lines.Add(Convert.ToDouble(line));
}
Average(lines);
Console.ReadLine();
Now your average method becomes
private static void Average(List<double> lines) {
Console.WriteLine(lines.Average());
}
Note that you should handle the case where the input is not a number.
static void Main(string[] args)
{
Console.WriteLine("Enter number(s): ");
string input = "";
List<double> doubleList = new List<double>();
while (input != "q")
{
input = Console.ReadLine();
if(input != "q")
{
try
{
doubleList.Add(Convert.ToInt32(input));
}
catch
{
Console.WriteLine("Invalid input");
}
}
}
average(doubleList);
Console.ReadKey();
}
static void average(List<double> myList)
{
double sum = 0;
Console.Write("You have entered: ")
foreach (int element in myList)
{
sum += element;
Console.Write(element + ", ");
}
Console.WriteLine("");
double avg = sum / myList.Count;
Console.WriteLine("The average is: " + avg);
}
static void Main(string[] args)
{
var numbers = new List<double>();
Console.WriteLine("Enter the three numbers, one per line");
for (var i = 0; i < 3; ++i)
{
while (true)
{
if (double.TryParse(Console.ReadLine(), out var enteredNumber))
{
//the number is a number, so...
numbers.Add(enteredNumber);
break;
}
//if not a number...
Console.WriteLine("That's not a number, try again");
}
}
Average(numbers);
Console.ReadKey();
}
static void Average(IEnumerable<double> numbers)
{
var average = numbers.Average();
Console.Write("You have entered: ");
foreach (var num in numbers)
{
Console.Write($" {num} ");
}
Console.WriteLine(String.Empty);
Console.WriteLine("The average is: " + average);
}
In general, Lists are better than Arrays for this kind of thing; List's are stretchy, Arrays are not. If you want this to work with 4 (or 200) numbers, all you have to do is change the for loop's bounds.
I'm using double.TryParse, this way I can let the user correct a badly entered number (always assume users will enter bad data). I'm passing the collection of numbers to the average function as an IEnumerable and not a List (the Average function is hardly needed (note that the calculation of the average is just an extension method on collections of numerics) but you had one, so I included it. An IEnumerable cannot be changed by the called function, so it's more appropriate here (and, all lists (and all arrays, for that matter) are enumerable).
Looking at all these fancy answers,i guess people are forgetting the basics of programming.
The OP literally states using arrays and instead of that you all are pushing him into hard to read code. The guy is trying to learn the basics which obviously no one cares to learn about.
Dear Cyrus don't get into generics right away. I would suggest that you stick to arrays for a while.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter number(s): ");
double[] values = new double[3]; //initialize double array with its size
for (int i = 0; i < values.Length; i++)
{
//iterate through the array and assign value to each index of it.
values[i]=Convert.ToDouble(Console.ReadLine());
}
average(values);
Console.ReadKey();
}
//set method that accepts double array as parameter
static void average(double[] values)
{
double average =0;// declare var that will hold the sum of numbers
int length = values.Length;//get array length, use it to divide the summation of numbers
Console.WriteLine("You have entered: ");
for (int i = 0; i < values.Length; i++)
{
//also display the numbers if you need to
Console.WriteLine(values[i]);
//iterate through each value in the array and sum it up.
average = values[i] + average;
}
//divide the sum of numbers by the length of array
Console.WriteLine("The average is: " + (average/length));
}
}
You can also dynamically set the length of the array by letting the user input its length, just play with code and let your imagination loose. Happy coding!
You have a couple options. Either ask for the user input to be delimited somehow. For example a comma delimited user input would be"1, 2, 3, 4". You've then got to worry about parsing that and ensuring the user entered valid input.
Another option is to have a while loop that has Console.ReadLine() within, and you only exit the loop when the user enters a pre-determined exit word (such as "stop" or exit")
static void Main(string[] args)
{
var inputValues = new List<double>();
while (true)
{
var input = Console.ReadLine();
if (input.Equals("stop", StringComparison.InvariantCultureIgnoreCase))
break;
if (double.TryParse(input, out double inputValue))
{
inputValues.Add(inputValue);
}
else
{
Console.WriteLine("Invalid input!");
}
}
PrintAverage(inputValues);
Console.ReadKey();
}
static void PrintAverage(IEnumerable<double> values)
{
Console.WriteLine("You have entered: {0}", string.Join(", ", values));
Console.WriteLine("The average is: {0}", values.Average());
}
Here I've opted for the second option. It'll continuously loop until the input is stop. It will also now try parse the value rather than directly convert, and will print a warning message if the parse failed.
If the parse was successful it's added to our inputValues collection. Once out of the while loop, we pass the collection to PrintAverage - a method that takes an IEnumerable<double> (could be one value, 100 values, or no values). Because List implements IEnumerable, we can pass our list to this method. IEnumerable has an Average() method built-in.