-1

I want to create a console calculator in C#. The data is read from a file called expressions.txt. The columns of the file consist of two numbers and an operation. I want to calculate using only the operation symbols in the file, with numbers of my choice. If I give the input a stop, it stops iterating and then exits the program. I would also like to do error handling. For example: if there is no operator in the list, I want to get a "wrong operator" message. If I want to divide by 0, or if I enter a string instead of a number, I want to get "other error" messages. I did something wrong in error handling. I would like to ask for help in correct error handling. Here is my code:


class Program
{

    // 1.Reading:
    static List<Expression> expressions = new List<Expression>();

    static void Read()
    {
        string[] rows = File.ReadAllLines("expressions.txt");
        foreach (var item in rows)
        {
            expressions.Add(new Expression(item));
        }

    }


    //counting:
    static void Calculator()
    {
        //string[] operators = { "div", "mod", "%", "/", "*", "-", "+" };
        string counting = "";
        string actionRequest = "";
        while (actionRequest != "stop")
        {
            Console.Write("\nI need an action:");
            actionRequest = Console.ReadLine();
            if (actionRequest != "stop")
            {
                string[] data = actionRequest.Split(' ');
                int firstNumber = int.Parse(data[0]);
                string symbol = Convert.ToString(data[1]);
                int secondNumber = int.Parse(data[2]);

                try
                {
                    counting = firstNumber + " " + symbol + " " + secondNumber;
                    switch (symbol)
                    {
                        case "mod":
                            actionRequest = counting + " = " + (firstNumber % secondNumber);
                            Console.WriteLine($"{counting} = {firstNumber % secondNumber}");
                            break;
                        case "div":
                            actionRequest = counting + " = " + (firstNumber / secondNumber);
                            Console.WriteLine($"{counting} = {firstNumber / secondNumber}");
                            break;
                        case "/":
                            actionRequest = counting + " = " + (Double.Parse(data[0]) / Double.Parse(data[2]));
                            Console.WriteLine($"{counting} = {Double.Parse(data[0]) / Double.Parse(data[2])}");
                            break;
                        case "*":
                            actionRequest = counting + " = " + (firstNumber * secondNumber);
                            Console.WriteLine($"{counting} = {firstNumber * secondNumber}");
                            break;
                        case "+":
                            actionRequest = counting + " = " + (firstNumber + secondNumber);
                            Console.WriteLine($"{counting} = {firstNumber + secondNumber}");
                            break;
                        case "-":
                            actionRequest = counting + " = " + (firstNumber - secondNumber);
                            Console.WriteLine($"{counting} = {firstNumber - secondNumber}");
                            break;
                        //default:          // --> that's the fault.
                        //    return ($"Bad operator!");
                    }
                }

                catch (Exception)
                {
                    Console.WriteLine($"Other error!");
                }



            }
            else
            {
                Console.Write("Exit ---> |press any key|");
                break;

            }



        }

    }

    static void Main(string[] args)
    {
        Read();
        Calculator();
        Console.ReadKey();
    }

}

Expression.cs:

class Expression
{

    public int op1, op2;
    public string operation;

    // ctor
    public Expression(string row)
    {
        op1 = Convert.ToInt32(row.Split()[0]);
        operation = row.Split()[1];
        op2 = Convert.ToInt32(row.Split()[2]);
    }

}

Here is the expressions.txt for the exercise:

enter image description here

Am_I_Helpful
  • 18,735
  • 7
  • 49
  • 73
  • "I did something wrong in error handling" And what exactly do you think is whrong? Do you get any error? Unexpected behaviour? Please provide more info on what you expect and what you get instead. – MakePeaceGreatAgain Sep 27 '21 at 15:08
  • Did you step through your code with a debugger? – Daniel Mann Sep 27 '21 at 15:51
  • If static void Calculator() is set, then the default: return ($"Bad operator!"); will fail, since there is no return value due to the void. This is clear. So I set a static string Calculator(). But this is not good either, because the Calculator name will be underlined. I do not understand the reason for the error. Also I would like the try catch to run as described above. So only numbers can be entered, division by 0 should not be possible. But I don't know how to implement this. – Jackie Frei Sep 30 '21 at 10:49

1 Answers1

1

Let's extract model (all possible operations) first:

static Dictionary<string, Func<double, double, double>> s_Operations = new
  Dictionary<string, Func<double, double, double>>(StringComparer.OrdinalIgnoreCase) {
    {"+",   (a, b) => a + b},
    {"-",   (a, b) => a - b},
    {"*",   (a, b) => a * b},
    {"/",   (a, b) => a / b},
    {"%",   (a, b) => a % b},
    {"div", (a, b) => a / b - a % b}, // integer division
    {"mod", (a, b) => a % b},  
    // Add more operations if required, e.g. "pow"      
  };

Keep on extracting: we are ready to implement Compute:

   static string Compute(string line) {
     if (line == null)
       return "null";

     // The simplest; spaces are mandatory: 
     // "3 + 4" is valid, when "3 +4", "3+ 4", "3+4" are not
     string[] items = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);

     // if we have exactly three items: double, func, double
     // we can compute the formula
     if (items.Length == 3 &&
         double.TryParse(items[0], out var a) &&
         s_Operations.TryGetValue(items[1], out var func) &&
         double.TryParse(items[2], out var b)) 
       return $"{string.Join(" ", items)} = {func(a, b)}";
     else
       return "Syntax error";
   }  

Then we can easily process the file...

   static void Calulator() {
     foreach (var line in File.ReadLines(@"c:\myFile.txt")) {
       if (line.Trim() == "stop")
         break;

       Console.WriteLine(Compute(line));    
     }
   }

Note, that the only possible errors in this case ane number / 0 which is either +Inf or -Inf and 0 / 0 which is NaN (Not a Number).

... or implement console input:

   static void Calulator() {
     while (true) {
       Console.Write("\nI need an action:");

       string actionRequest = Console.ReadLine().Trim();

       if (actionRequest == "stop")
         break;

       Console.WriteLine(Compute(actionRequest));    
     }
   }
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215