Related
I am new so I don't know why I am getting such an exception and also I don't know how to explain so here is the code
using System;
namespace math
{
class Math
{
int add(int a, int b)
{
return a + b;
}
static void Main(string[] args)
{
Math math = new Math();
int result = 0;
for (int i = 0; i < args.Length; i++)
{
switch(args[i])
{
case "+":
result = math.add(int.Parse(args[i--]), int.Parse(args[i++]));
break;
default:
break;
}
}
Console.WriteLine(result);
Console.ReadLine();
}
}
}
this is the whole exception from VS Code
Exception has occurred: CLR/System.FormatException
An unhandled exception of type 'System.FormatException' occurred in System.Private.CoreLib.dll: 'Input string was not in a correct format.'
at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)
at System.Number.ParseInt32(ReadOnlySpan`1 value, NumberStyles styles, NumberFormatInfo info)
at System.Int32.Parse(String s)
at math.Math.Main(String[] args) in D:\tmp\math\Program.cs:line 20
Edit : This is a command line program like "whoami" or like "g++"?
You are modifying your loop index here:
result = math.add(int.Parse(args[i--]), int.Parse(args[i++]));
This will result in you reading the "+" again rather than the numbers you're expecting, which is why you're getting the FormatException.
Change the line to:
result = math.add(int.Parse(args[i - 1]), int.Parse(args[i + 1]));
This is easier to understand and doesn't mess with the loop index.
This will still fail if someone enters "a + b" (say), so you should really check that the values are integers:
int first;
int second;
if (int.TryParse(args[i-1], out first) &&
int.TryParse(args[i+1], out second))
{
result = first + second;
}
else
{
// Error: both values need to be numeric
}
Following would be an simple alternative to start with if it is C#.
class Math
{
int add(int a, int b)
{
return a + b;
}
static void Main(string[] args)
{
Math math = new Math();
Console.Write("Enter Integer: ");
var val1 = Console.ReadLine();
int a = Convert.ToInt32(val1);
Console.Write("Enter Integer: ");
var val2 = Console.ReadLine();
int b = Convert.ToInt32(val2);
Console.Write("Enter Operation: ");
var operation = Console.ReadLine();
int result = 0;
switch(operation)
{
case "+":
result = math.add(a, b);
break;
default:
break;
}
Console.WriteLine(result);
Console.ReadLine();
}
}
I am a student and got a task where I will have to make a program that solves first-grade equations. I will start of by making a textbox where I can write down different numbers of all the arithmetics, for example, 3+4*8 (it doesn't have to follow the priority rules) and then when I press the "go" button I get the answer.
I tried using the split method from this question/answer:
C# read and calculate multiple values from textbox and it worked for addition but then I tried to use the same script and change it up a little to make it work for multiplication and subtraction but it did not work.
The scripts that I have tried are:
string[] parts = tbxTal.Text.Split('+');
int intSumma = 0;
foreach (string item in parts)
{
intSumma = intSumma + Convert.ToInt32(item);
}
lblSvar.Text = intSumma.ToString();
Also tried using switch (+) after the split but it did not work since there is not + left after te splitt
Any Idea on how I can make a textbox that calculates everything inside of it? My teacher gave me a tip to use the split method and case method together.
Without giving the answer overtly, I would suggest that you keep a variable for the accumulator, operator, and operand. From there you can use a for loop to keep reading until you've evaluated all of the expression, then return the accumulator.
double Evaluate(string expression) {
double accumulator = 0;
double operand = 0;
string operator = string.Empty;
int index = 0;
while (index < expression.Length) {
operand = ExtractNextNumericValue(ref index, expression);
operator = ExtractNextOperator(ref index, expression);
// We now have everything we need to do the math
...
}
return accumulator;
}
public double ExtractNextNumericValue(ref index, string expression) {
// Use IndexOf on the string, use the index as a start location
// Make sure to update ref to be at the end of where you extracted your value
// You know that the value will come before an operator, so look for '+', '-', '*', '/'
...
}
One thing that should help you with creating a calculator like this is reversed Polish notation. Accepted answer to this question is a working calculator that can handle order of operations etc.
Code from mentioned post:
static void Main(string[] args)
{
String str = "5 + ( ( 1 + 2 ) * 4 ) −3";
String result=LengyelFormaKonvertalas(str);
Console.WriteLine(result.ToString());
Console.ReadLine();
}
static String LengyelFormaKonvertalas(String input) // this is the rpn method
{
Stack stack = new Stack();
String str = input.Replace(" ",string.Empty);
StringBuilder formula = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
char x=str[i];
if (x == '(')
stack.Push(x);
else if (IsOperandus(x)) // is it operand
{
formula.Append(x);
}
else if (IsOperator(x)) // is it operation
{
if (stack.Count>0 && (char)stack.Peek()!='(' && Prior(x)<=Prior((char)stack.Peek()) )
{
char y = (char)stack.Pop();
formula.Append(y);
}
if (stack.Count > 0 && (char)stack.Peek() != '(' && Prior(x) < Prior((char)stack.Peek()))
{
char y = (char)stack.Pop();
formula.Append(y);
}
stack.Push(x);
}
else
{
char y=(char)stack.Pop();
if (y!='(')
{
formula.Append(y);
}
}
}
while (stack.Count>0)
{
char c = (char)stack.Pop();
formula.Append(c);
}
return formula.ToString();
}
static bool IsOperator(char c)
{
return (c=='-'|| c=='+' || c=='*' || c=='/');
}
static bool IsOperandus(char c)
{
return (c>='0' && c<='9' || c=='.');
}
static int Prior(char c)
{
switch (c)
{
case '=':
return 1;
case '+':
return 2;
case '-':
return 2;
case '*':
return 3;
case '/':
return 3;
case '^':
return 4;
default:
throw new ArgumentException("Rossz paraméter");
}
}
}
Change below line of code from this article C# read and calculate multiple values from textbox
like this:
string[] parts = textBox1.Text.Split('+');
Replace above line with below line
string[] parts = textBox1.Text.Split('+','*','-');
I am making a C# maths project where the user answers an addition, subtraction, multiplication, division, power or square root question based on the difficulty level they choose!
I have just started using Enums but I don't know how to put it in my switch statements so the rest of my code works fine.
Here is my code so far:
using System;
namespace mathstester
{
class Program
{
public enum UserDifficulty
{
Easy,
Normal,
Hard
}
public enum MathOperation
{
Addition = 1,
Subtraction = 2,
Multiplication = 3,
Division = 4,
Power = 5,
SquareRoot = 6
}
public static (int operationMin, int operationMax) GetMathOperationForDifferentDifficulties(UserDifficulty userDifficulty)
{
switch (userDifficulty)
{
case UserDifficulty.Easy:
return (1, 4);
case UserDifficulty.Normal:
return (1, 5);
case UserDifficulty.Hard:
return (3, 7);
default:
throw new Exception();
}
}
public static (string message, double correctAnswer) GetMathsEquation(MathOperation mathOperation, UserDifficulty userDifficulty)
{
int number1;
int number2;
Random random = new Random();
switch (mathOperation)
{
case MathOperation.Addition:
number1 = random.Next(1000);
number2 = random.Next(1000);
return ($"{number1} + {number2}", number1 + number2);
case MathOperation.Subtraction:
number1 = random.Next(1000);
number2 = random.Next(1000);
return ($"{number1} - {number2}", number1 - number2);
case MathOperation.Multiplication:
number1 = userDifficulty == UserDifficulty.Easy ? random.Next(13) : random.Next(1000);
number2 = userDifficulty == UserDifficulty.Easy ? random.Next(13) : random.Next(1000);
return ($"{number1} * {number2}", number1 * number2);
case MathOperation.Division:
number1 = random.Next(10000);
number2 = random.Next(1000);
return ($"{number1} / {number2}", number1 / (double)number2);
case MathOperation.Power:
number1 = random.Next(13);
number2 = random.Next(5);
return ($"{number1} ^ {number2}", Math.Pow(number1, number2));
case MathOperation.SquareRoot:
number1 = random.Next(1000);
return ($"√{number1}", Math.Sqrt(number1));
default:
throw new Exception();
}
}
public static int GetResult(int numberOfQuestionsLeft, string userDifficulty)
{
int score = 0;
Random random = new Random();
var (operationMin, operationMax) = GetMathOperationForDifferentDifficulties(userDifficulty);
while (numberOfQuestionsLeft > 0)
{
int mathOperation = random.Next(operationMin, operationMax);
var (message, correctAnswer) = GetMathsEquation(mathOperation, userDifficulty);
if (mathOperation == 4 || mathOperation == 6)
{
Console.Write($"To the nearest integer, What is {message} =");
}
else
{
Console.Write($"What is {message} =");
}
double userAnswer = Convert.ToDouble(Console.ReadLine());
if (Math.Round(correctAnswer) == userAnswer)
{
Console.WriteLine("Well Done!");
score++;
}
else
{
Console.WriteLine("Your answer is incorrect!");
}
numberOfQuestionsLeft--;
}
return score;
}
public static void Main(string[] args)
{
string userDifficulty = "";
do
{
Console.WriteLine("What difficulty level would you like to do! Please type E for Easy, N for Normal and H for hard");
userDifficulty = Console.ReadLine().ToUpper();
} while (userDifficulty != "E" && userDifficulty != "N" && userDifficulty != "H");
int numberOfQuestions = 0;
do
{
Console.WriteLine("How many questions would you like to answer? Please type a number divisible by 10!");
int.TryParse(Console.ReadLine(), out numberOfQuestions);
} while (numberOfQuestions % 10 != 0);
int score = GetResult(numberOfQuestions, userDifficulty);
Console.WriteLine($"You got a score of {score} out of {numberOfQuestions}");
}
}
}
Your issue seems to lie in the selection of difficulties - in your Main() method, you take an input of E, N, or H for difficulty, which is then passed to GetResult() and onwards to GetMathOperationForDifferentDifficulties()
However, as Enums are underpinned by a numeric type in C#, this will fail and throw an exception.
To fix it, you need to convert the E, N, or H to UserDifficulty.Easy, UserDifficulty.Normal, or UserDifficulty.Hard respectively, and then pass them over that way.
Here's how you could modify Main() to do this:
public static void Main(string[] args)
{
string difficultyInput = "";
UserDifficulty userDifficulty = UserDifficulty.Easy // default to start
do
{
Console.WriteLine("What difficulty level would you like to do! Please type E for Easy, N for Normal and H for hard");
difficultyInput = Console.ReadLine().ToUpper();
} while (difficultyInput != "E" && difficultyInput != "N" && difficultyInput != "H");
switch(difficultyInput) {
case "E":
userDifficulty = UserDifficulty.Easy;
break;
case "N":
userDifficulty = UserDifficulty.Normal;
break;
case "H":
userDifficulty = UserDifficulty.Hard;
break;
}
int numberOfQuestions = 0;
do
{
Console.WriteLine("How many questions would you like to answer? Please type a number divisible by 10!");
int.TryParse(Console.ReadLine(), out numberOfQuestions);
} while (numberOfQuestions % 10 != 0);
int score = GetResult(numberOfQuestions, userDifficulty);
Console.WriteLine($"You got a score of {score} out of {numberOfQuestions}");
}
Bear in mind you'd need to alter GetResult() to take a UserDifficulty input instead of a string, too
I am looking to generate a Sequence Number in this format
00000A
00000B
00000B
and so on till
00000Z
and then
00001A
00001B
00001C
...
00001Z
...
00010A
till
99999Z
I know that I can generate Max 2.6 million rows using this method but I guess that is enough
so, if I have the a String, lets say 26522C, Now i want the next number as 26522D
or If I have 34287Z, i want 34288A
I can write the Algorithm about it but there will be lots of parsing of the input string characters by characters
I was wondering is there any easier way of doing it
String GetNextNumberInSequence(String inputString)
{
if (inputString.Length == 6)
{
var charArray = inputString.ToCharArray();
char[] inputChars = { charArray[0], charArray[1], charArray[2],charArray[3],charArray[4],charArray[5] };
if(Char.IsDigit(charArray[5]))
{
//Parse first 5 characters
}
}
}
private static String GetNextNumberInSequence(String inputString)
{
var integerpart = int.Parse(inputString.Substring(0, 5));
var characterPart = inputString[5];
if (characterPart == 'Z')
return string.Format("{0}{1}", (++integerpart).ToString("D5"), "A");
var nextChar = (char)(characterPart + 1);
return string.Format("{0}{1}", (integerpart).ToString("D5"), nextChar.ToString());
}
You can achieve this by converting a number to Base36.
Take a look at this sample:
private const string CharList = "0123456789abcdefghijklmnopqrstuvwxyz";
public static String Base36Encode(long input, char paddingChar, int totalWidth)
{
char[] clistarr = CharList.ToCharArray();
var result = new Stack<char>();
while (input != 0)
{
result.Push(clistarr[input % 36]);
input /= 36;
}
return new string(result.ToArray()).PadLeft(totalWidth, paddingChar).ToUpper();
}
and then use it this way:
for(int i = 0; i < 1000; i++)
{
Debug.WriteLine(Base36Encode(i, '0', 6));
}
which will produce this:
000000, 000001, 000002, 000003, 000004, 000005, 000006, 000007, 000008, 000009, 00000A, 00000B, 00000C, 00000D, 00000E, 00000F, 00000G, 00000H, 00000I, 00000J, 00000K, 00000L, 00000M, 00000N, 00000O, 00000P, 00000Q, 00000R, 00000S, 00000T, 00000U, 00000V, 00000W, 00000X, 00000Y, 00000Z, 000010, 000011, 000012, 000013, 000014, 000015, 000016, 000017, 000018, 000019, 00001A, 00001B, 00001C, 00001D, 00001E, 00001F, 00001G, 00001H, 00001I, 00001J, 00001K, 00001L, 00001M, 00001N, 00001O, 00001P, 00001Q, 00001R, 00001S, 00001T, 00001U, 00001V, 00001W, 00001X, 00001Y, 00001Z, 000020, 000021, 000022, 000023, 000024, 000025, 000026, 000027, 000028, 000029, 00002A, 00002B, 00002C, 00002D, 00002E, 00002F, 00002G, 00002H, 00002I, 00002J, 00002K, 00002L, 00002M, 00002N, 00002O, 00002P, 00002Q, 00002R, 00002S, 00002T...
and the positive thing about this approach is that you can convert this back to number by using:
public static Int64 Base36Decode(string input)
{
var reversed = input.ToLower().Reverse();
long result = 0;
int pos = 0;
foreach (char c in reversed)
{
result += CharList.IndexOf(c) * (long)Math.Pow(36, pos);
pos++;
}
return result;
}
i know how to make a console read two integers but each integer by it self like this
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
if i entered two numbers, i.e (1 2), the value (1 2), cant be parse to integers
what i want is if i entered 1 2 then it will take it as two integers
One option would be to accept a single line of input as a string and then process it.
For example:
//Read line, and split it by whitespace into an array of strings
string[] tokens = Console.ReadLine().Split();
//Parse element 0
int a = int.Parse(tokens[0]);
//Parse element 1
int b = int.Parse(tokens[1]);
One issue with this approach is that it will fail (by throwing an IndexOutOfRangeException/ FormatException) if the user does not enter the text in the expected format. If this is possible, you will have to validate the input.
For example, with regular expressions:
string line = Console.ReadLine();
// If the line consists of a sequence of digits, followed by whitespaces,
// followed by another sequence of digits (doesn't handle overflows)
if(new Regex(#"^\d+\s+\d+$").IsMatch(line))
{
... // Valid: process input
}
else
{
... // Invalid input
}
Alternatively:
Verify that the input splits into exactly 2 strings.
Use int.TryParse to attempt to parse the strings into numbers.
You need something like (no error-checking code)
var ints = Console
.ReadLine()
.Split()
.Select(int.Parse);
This reads a line, splits on whitespace and parses the split strings as integers. Of course in reality you would want to check if the entered strings are in fact valid integers (int.TryParse).
Then you should first store it in a string and then split it using the space as token.
Read the line into a string, split the string, and then parse the elements. A simple version (which needs to have error checking added to it) would be:
string s = Console.ReadLine();
string[] values = s.Split(' ');
int a = int.Parse(values[0]);
int b = int.Parse(values[1]);
string[] values = Console.ReadLine().Split(' ');
int x = int.Parse(values[0]);
int y = int.Parse(values[1]);
in 1 line, thanks to LinQ and regular expression (no type-checking neeeded)
var numbers = from Match number in new Regex(#"\d+").Matches(Console.ReadLine())
select int.Parse(number.Value);
string x;
int m;
int n;
Console.WriteLine("Enter two no's seperated by space: ");
x = Console.ReadLine();
m = Convert.ToInt32(x.Split(' ')[0]);
n = Convert.ToInt32(x.Split(' ')[1]);
Console.WriteLine("" + m + " " + n);
This Should work as per your need!
public static class ConsoleInput
{
public static IEnumerable<int> ReadInts()
{
return SplitInput(Console.ReadLine()).Select(int.Parse);
}
private static IEnumerable<string> SplitInput(string input)
{
return Regex.Split(input, #"\s+")
.Where(x => !string.IsNullOrWhiteSpace(x));
}
}
int a, b;
string line = Console.ReadLine();
string[] numbers= line.Split(' ');
a = int.Parse(numbers[0]);
b = int.Parse(numbers[1]);
Try this:
string numbers= Console.ReadLine();
string[] myNumbers = numbers.Split(' ');
int[] myInts = new int[myNumbers.Length];
for (int i = 0; i<myInts.Length; i++)
{
string myString=myNumbers[i].Trim();
myInts[i] = int.Parse(myString);
}
Hope it helps:)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SortInSubSet
{
class Program
{
static int N, K;
static Dictionary<int, int> dicElements = new Dictionary<int, int>();
static void Main(string[] args)
{
while (!ReadNK())
{
Console.WriteLine("***************** PLEASE RETRY*********************");
}
var sortedDict = from entry in dicElements orderby entry.Key/3 , entry.Value ascending select entry.Value;
foreach (int ele in sortedDict)
{
Console.Write(ele.ToString() + " ");
}
Console.ReadKey();
}
static bool ReadNK()
{
dicElements = new Dictionary<int, int>();
Console.WriteLine("Please entere the No. of element 'N' ( Between 2 and 9999) and Subset Size 'K' Separated by space.");
string[] NK = Console.ReadLine().Split();
if (NK.Length != 2)
{
Console.WriteLine("Please enter N and K values correctly.");
return false;
}
if (int.TryParse(NK[0], out N))
{
if (N < 2 || N > 9999)
{
Console.WriteLine("Value of 'N' Should be Between 2 and 9999.");
return false;
}
}
else
{
Console.WriteLine("Invalid number: Value of 'N' Should be greater than 1 and lessthan 10000.");
return false;
}
if (int.TryParse(NK[1], out K))
{
Console.WriteLine("Enter all elements Separated by space.");
string[] kElements = Console.ReadLine().Split();
for (int i = 0; i < kElements.Length; i++)
{
int ele;
if (int.TryParse(kElements[i], out ele))
{
if (ele < -99999 || ele > 99999)
{
Console.WriteLine("Invalid Range( " + kElements[i] + "): Element value should be Between -99999 and 99999.");
return false;
}
dicElements.Add(i, ele);
}
else
{
Console.WriteLine("Invalid number( " + kElements[i] + "): Element value should be Between -99999 and 99999.");
return false;
}
}
}
else
{
Console.WriteLine(" Invalid number ,Value of 'K'.");
return false;
}
return true;
}
}
}
I have a much simpler solution, use a switch statement and write a message for the user in each case, using the Console.write() starting with a ("\n").
Here's an example of filling out an array with a for loop while taking user input. * Note: that you don't need to write a for loop for this to work*
Try this example with an integer array called arrayOfNumbers[] and a temp integer variable. Run this code in a separate console application and Watch how you can take user input on the same line!
int temp=0;
int[] arrayOfNumbers = new int[5];
for (int i = 0; i < arrayOfNumbers.Length; i++)
{
switch (i + 1)
{
case 1:
Console.Write("\nEnter First number: ");
//notice the "\n" at the start of the string
break;
case 2:
Console.Write("\nEnter Second number: ");
break;
case 3:
Console.Write("\nEnter Third number: ");
break;
case 4:
Console.Write("\nEnter Fourth number: ");
break;
case 5:
Console.Write("\nEnter Fifth number: ");
break;
} // end of switch
temp = Int32.Parse(Console.ReadLine()); // convert
arrayOfNumbers[i] = temp; // filling the array
}// end of for loop
The magic trick here is that you're fooling the console application, the secret is that you're taking user input on the same line you're writing your prompt message on. (message=>"Enter First Number: ")
This makes user input look like is being inserted on the same line. I admit it's a bit primitive but it does what you need without having to waste your time with complicated code for a such a simple task.