-1

So, I am refreshing myself on C#. I decided to write a simple calculator program and was showing my daughter. I added a while loop to my main and added an if statement to break the loop if the user doesn't want to repeat the process...I added some methods for the operators and added some info at the end. After that it stopped repeating and just totally skips getting input from the "x = (char)Console.Read();" line and exits. Helpful advice would be appreciated, I am still a beginner with coding so please don't criticize me, thanks. Full code below:

  using System;

  namespace TrueCalculator
  {
   class Program
   {
    public static int addition(int num1, int num2)
    {
        int result = num1 + num2;
        return result;
    }
    public static int subtraction(int num1, int num2)
    {
        int result = num1 - num2;
        return result;
    }
    public static int division(int num1, int num2)
    {
        int result = num1 / num2;
        return result;
    }
    public static int multiplication(int num1, int num2)
    {
        int result = num1 * num2;
        return result;
    }
    static void Main(string[] args)
    {
        char x = 'y';
        while (x == 'y' || x == 'Y')
        {
            Console.WriteLine("\t\t\tTrue Calculator\n\t\t    Only uses whole numbers!\n\t\t       ***BETA VERSION***");
            
            Console.WriteLine("Enter first number: ");
            int num1 = Convert.ToInt32(Console.ReadLine());
            
            Console.WriteLine("Enter second number: ");
            int num2 = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("Please type desired operator to perform: +, -, /, *");
            char op = (char)Console.Read();

            if (op == '+')
            {
                Console.WriteLine(num1 + " + " + num2 + " = " + addition(num1, num2));
            }
            else if (op == '-')
            {
                Console.WriteLine(num1 + " - " + num2 + " = " + subtraction(num1, num2));
            }
            else if (op == '/')
            {
                Console.WriteLine(num1 + " / " + num2 + " = " + division(num1, num2));
            }
            else if (op == '*')
            {
                Console.WriteLine(num1 + " * " + num2 + " = " + multiplication(num1, num2));
            }

            Console.WriteLine("Reset, y/n?");
            x = Convert.ToChar(Console.Read());

            if (x == 'n' || x == 'N')
            {
                break;
            }
        }
        
        Console.WriteLine("\n\n\t\t\tThank you for using True Calculator\n\nDeveloped by Duster_2015..." + 
            "\nAny comments or suggestions send to: " +
            "FIXME: Enter your Duster email.");
        Console.ReadKey();

    }
}

}

  • I'm guessing `Console.Read()` leaves the newline and you are reading that the 2nd time? You can use `x = Console.ReadLine()[0];` – 001 Jul 08 '21 at 18:54
  • there's probably some character still in the read buffer, such as a `\n` – Cid Jul 08 '21 at 18:55
  • I tried Console.ReadLine()[0]; but I get an exception "Out of Range". How do I check the read buffer? – Christopher Katz Jul 08 '21 at 19:03
  • I changed x = Convert.ToChar(Console.Read()); to x = (char)Console.Read(); just for the readability. I still haven't figured why it skips the line entirely then automatically breaks the loop and exits. I mean I have the break; in an if statement. – Christopher Katz Jul 08 '21 at 19:05
  • It is exiting the loop because when you type `y` there are 3 characters in the console buffer to be read: `y \r \n` (on Windows). So the first time you call `Console.Read()` you get the `y` and the loop repeats. The next time it reads the `\r` that's been sitting there from the first time through. Since `'\r' != 'y'` and `'\r' != 'Y'` the loop ends. `Console.ReadLine()` consumes and discards the `\r\n` for you. – 001 Jul 08 '21 at 19:08
  • I never get to type y. It outputs Reset, y/n? then exits the loop automatically. If anyone could copy my code and try it to see how it is acting. Thanks for all the insight so far everyone. – Christopher Katz Jul 08 '21 at 19:12
  • That's because of the `char op = (char)Console.Read();` (I missed that). But it is the same issue. – 001 Jul 08 '21 at 19:14
  • Ok...I tried following it using the debugger but as soon as it executes the desired method and displays Console.WriteLine("Reset, y/n?"); it just jumps out of loop...So I commented out Console.WriteLine(..thank you for using... at the bottom but left the Console.ReadKey(); For some reason it works perfectly now, but if I add my thank you for using line back it starts skipping again?? I am confused. – Christopher Katz Jul 08 '21 at 19:29
  • I copied your code and replaced both occurrences of `Console.Read()` to `Console.ReadLine()[0]` and it all works fine. – 001 Jul 08 '21 at 19:34
  • @ChristopherKatz read again the duplicate link I provided about an hour ago – Cid Jul 08 '21 at 19:46
  • Thank you, I didn't realize you wanted me to change both read(). Quick question, why did that solve my problem? What am I not understanding? Again thanks. – Christopher Katz Jul 08 '21 at 19:54

1 Answers1

0

(This applies to Windows which uses \r\n for newlines. Other systems use only \n.)

When the program asks you to enter "+, -, /, *" and you type

+enter

three chars are put into the console's buffer:

+\r\n

These chars sit there until you read them (or flush them). When you do

char op = (char)Console.Read();

Only one of those chars is read. The variable op is assigned to '+' and the + is removed from the console's input buffer, but the buffer still has

\r\n

in it - just waiting to be read.

Then when you do

x = Convert.ToChar(Console.Read());

it sees the \r in the buffer and it is read immediately - you don't get a chance to type anything and x is assigned '\r'. When the loop rolls back to the beginning, (x == 'y' || x == 'Y') is false and it ends.

One solution is to not use Console.Read() and use Console.ReadLine() instead. This reads the entire input buffer - up to and including the next \n - but neither the \r nor the \n are included in the result. Then you can use string comparisons:

string op = Console.ReadLine();
if (op == "+")....

If you want to use char instead, you need to check for blank strings:

string op = Console.ReadLine();
if (!String.IsNullOrEmpty(op)) {
    if (op[0] == '+') ....
001
  • 13,291
  • 5
  • 35
  • 66
  • Thank you @Johnny Mopp for your patience. Sorry my post was a "duplicate" but I don't go looking for easy answers, I would rather ask and have someone explain the problem to me so I can learn. It is too easy now-a-days to just google an answer and not worry about understanding why. Thank you for the explanation, you just made me that much better. – Christopher Katz Jul 09 '21 at 12:41