0

I'm studying a C # course and doing my second task. I've been able to get the code done. The only thing I can´t code is how to use and where to use Try & Catch. Since I'm new to C #, I don´t know how to code it.

I've searched for solution but most of it is within Java.

The task is that an American should enter the sauna and the sauna shows only Celsius degrees. You enter Fahrenheit degrees and it converts to Celsius degrees. Degrees for okey warmth of the sauna are 73-77C degrees.

Here is my code:

public static int FahrToCel(int fahr)
    {
        int cel = (fahr - 32) * 5 / 9;
        return cel;
    }

    public static void Main(string[] args)
    {
        Console.WriteLine("Skriv in Fahrenheit: ");
        int fahrenheit = int.Parse(Console.ReadLine());
        //Användaren skriver in ett värde som lagras i fahrenheit
        int celsius = FahrToCel(fahrenheit);
        /* I celsius finns nu antal grader omvandlat från fahrenheit till celsius. */

        /*Här får lowerTempLimit värdet 77 
         * &  upperTempLimit = 77 */
        int lowerTempLimit = 73;
        int upperTempLimit = 77;

        /* While-do loop som breaker efter en iteration.
        *If satserna skriver utvärmen i bastun och säger till om temperatur ska sänkas eller höjas beroende på temperaturn i celsius. 
        * Om temperaturn är mellan 73 - 77 grader, så har bastun godtyckligt bra temperatur */
        do
        {
            if (celsius < lowerTempLimit)
            {
                Console.WriteLine("Bastun är inte tillräckligt varmt. Värme i bastun {0}, skruva upp värmen", celsius);
            }
            else if (celsius > upperTempLimit)
            {
                Console.WriteLine("Bastun är för varmt. Värme i bastun {0}, skruva ner värmen", celsius);
            }
            else
            {
                Console.WriteLine("Bastun är tillräckligt varmt för att kunna basta. Värme i bastun {0}", celsius);
            }
        }
        while (celsius < lowerTempLimit || celsius > upperTempLimit);

        Console.Write("Press any key to continue . . . ");
        Console.ReadKey();
    }
S. Gunel
  • 13
  • 1
  • 6
  • 1
    Why do you think you need a `Try... Catch` block? – Faruq Mar 23 '18 at 20:23
  • I need it so that users can´t write letters. Users shall only write integers. – S. Gunel Mar 23 '18 at 20:43
  • 2
    In this case, use `int.TryParse()` method https://msdn.microsoft.com/en-us/library/system.int32.tryparse(v=vs.110).aspx. This will not throw any exception, but will return `false` if the user enters anything other than integers. Usually, throwing exception is very expensive in C#. So, try to avoid them as much as possible and use only when there is no other option. – Faruq Mar 23 '18 at 20:49
  • Relevant: https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/ – Xam Mar 23 '18 at 21:06

4 Answers4

3

Main is a top-level method; it is called only by the operating system. In general, top level methods should have some form of exception handling. Otherwise, any exception that occurs in your code will propagate to the operating system itself, and that usually doesn't result in the most friendly UI.

To add top level exception handling to a console application is relatively easy.

public static void Main(string[] args)
{
    try
    {
        //Put all of your code here
    }
    catch (System.Exception ex)
    {
        Console.WriteLine("A problem has occurred and the application will now exit. Details: {0}", ex.Message);
    }
}

That's the most basic thing you can do. You might also consider writing to the event log or an application debug log, or providing additional information if the user is likely to be able to understand it.

In addition, there may be cases where your code will throw an exception and you want to handle it, i.e. not just exit the application. In those cases, you should wrap the specific area of risk with a try block as well.

Now in your case, there is actually very little code that could throw an exception (other than something catastrophic, such as the O/S running out of memory or something like that). The only line really is

 int fahrenheit = int.Parse(Console.ReadLine());

and you could do

 //Don't do this
 while (true)
 {
     try
     {
         int fahrenheit = int.Parse(Console.ReadLine());
         break;
     }
     catch (FormatException ex)
     {
         Console.WriteLine("Nummer nicht gut!!!")
     }
}

But you could easily replace that with a call to TryParse which would avoid the possibility of exception. That would be a better practice than wrapping Parse in its own try block; a try block would be overkill here and would hurt performance in what is probably a common use case (user accidentally enters a non-numeric string).

 int fahrenheit;
 while (true)
 {
     if (int.TryParse(Console.ReadLine(), out fahrenheit)) break;
     Console.WriteLine("Achtung!  Nummer kaput!");
 }

If you do decide to use try/catch instead of TryParse, note that it is a better idea to catch FormatException than to catch System.Exception, since you only want to handle the format exception. See also Why catch(Exception) is bad.

John Wu
  • 50,556
  • 8
  • 44
  • 80
  • I'm not sure advising the OP to wrap 'all' of their code in the try-catch is helpful. The OP states they are in a course, and the purpose of the task is most likely to learn about exception handling. Part of that learning is why to use it, and how to identify code that needs it. – Andrew_CSE Mar 23 '18 at 20:42
  • One reason to use it is when you are writing a top level method, so I think in that respect it is helpful. I'll add some more though. Thanks for the feedback. – John Wu Mar 23 '18 at 20:43
  • Also, because the OP has stated they are in a course, they may not be able to use methods like TryParse. That could cause academic repercussions using concepts not covered in the course. – Andrew_CSE Mar 23 '18 at 20:45
0

The try-catch block is for catching and handling exceptions. For example, you ask the user for numeric input and they put in letters. Without a try-catch, when you try to parse the input for numbers, and the parser encounters non-digits, it will halt and throw an exception. The try-catch allows your program to intercept the exception, handle it gracefully, and continue execution. The try block holds the code to be attempted, such as parsing the number, and the catch block holds the code for what to do when it fails.

Andrew_CSE
  • 351
  • 2
  • 6
  • I have read about it but don´t know exactly how I put and where in my code. Can I use it in the Do-While loop? If yes, how do I use it? – S. Gunel Mar 23 '18 at 20:31
  • Generally, the try-catch surrounds the code that could throw the exception. For example, from your code, `int fahrenheit = int.Parse(Console.ReadLine());` would become `try { int fahrenheit = int.Parse(Console.ReadLine()); } catch { ... what to do on error ... }` – Andrew_CSE Mar 23 '18 at 20:32
  • But in C# that's unnecessary because there are methods like `Int32.TryParse`, etc. – Xam Mar 23 '18 at 20:33
  • @Xam yes, but the OP states they are in a course, and may not be allowed to use TryParse. The OP specifically stated try-catch. – Andrew_CSE Mar 23 '18 at 20:36
0

try-catch are used to catch exceptions in your code and let you handle it (hopefully gracefully) instead of just crashing the program. I would have a try-catch when a user enters a numeric value. What happens when a user enters "a" and you try to parse that to a number? I've added it to you're example below:

public static void Main(string[] args)
{
    Console.WriteLine("Skriv in Fahrenheit: ");
    try
    {
        int fahrenheit = int.Parse(Console.ReadLine());
    }
    catch(Exception e)
    {
        //Do error handling i.e. prompt user for a valid number
    }

    //Användaren skriver in ett värde som lagras i fahrenheit
    int celsius = FahrToCel(fahrenheit);
    /* I celsius finns nu antal grader omvandlat från fahrenheit till celsius. */

    /*Här får lowerTempLimit värdet 77 
     * &  upperTempLimit = 77 */
    int lowerTempLimit = 73;
    int upperTempLimit = 77;

    /* While-do loop som breaker efter en iteration.
    *If satserna skriver utvärmen i bastun och säger till om temperatur ska sänkas eller höjas beroende på temperaturn i celsius. 
    * Om temperaturn är mellan 73 - 77 grader, så har bastun godtyckligt bra temperatur */
    do
    {
        if (celsius < lowerTempLimit)
        {
            Console.WriteLine("Bastun är inte tillräckligt varmt. Värme i bastun {0}, skruva upp värmen", celsius);
        }
        else if (celsius > upperTempLimit)
        {
            Console.WriteLine("Bastun är för varmt. Värme i bastun {0}, skruva ner värmen", celsius);
        }
        else
        {
            Console.WriteLine("Bastun är tillräckligt varmt för att kunna basta. Värme i bastun {0}", celsius);
        }
    }
    while (celsius < lowerTempLimit || celsius > upperTempLimit);

    Console.Write("Press any key to continue . . . ");
    Console.ReadKey();
}

PS: Exception are the highest form of an exception and will catch all exceptions. In you're case a FormatException would suffice.

Mats
  • 109
  • 2
  • 8
0

Thank you for all help everyone, I really appreciate it.

In my case I´m going to use the code below because my teacher talking about Try-Catch code.

            while (true)
            {
                try
                {
                    fahrenheit = int.Parse(Console.ReadLine());
                    break;
                }
                catch (FormatException ex)
                {
                    Console.WriteLine("Endast heltal kan matas in, försök igen!");
                    Console.WriteLine("\nSkriv in Fahrenheit grader: ");
                }
            }

This is my final code:

public static int FahrToCel(int fahr)
    {
        int cel = (fahr - 32) * 5 / 9;
        return cel;
    }

    public static void Main(string[] args)
    {
        int startTempLimit = 0;
        int lowerTempLimit = 73;
        int upperTempLimit = 77;
        int celsius;
        int fahrenheit;

        do
        {
            Console.WriteLine("Skriv in Fahrenheit grader: ");
            while (true)
            {
                try
                {
                    fahrenheit = int.Parse(Console.ReadLine());
                    break;
                }
                catch (FormatException ex)
                {
                    Console.WriteLine("Endast heltal kan matas in, försök igen!");
                    Console.WriteLine("\nSkriv in Fahrenheit grader: ");
                }
            }
            celsius = FahrToCel(fahrenheit);

            if (celsius < startTempLimit)
            {
                Console.WriteLine("Bastun är ej påslagen. Du måste sätta på bastun. Värme i bastu {0}C.", celsius);
            }
            else if (celsius < lowerTempLimit)
            {
                Console.WriteLine("Bastun är inte tillräckligt varm. Värme i bastun {0}C, skruva upp värmen", celsius);
            }
            else if (celsius > upperTempLimit)
            {
                Console.WriteLine("Bastun är för varm. Värme i bastun {0}C, skruva ner värmen", celsius);
            }
            else
            {
                Console.WriteLine("Bastun är tillräckligt varm för att kunna basta. Värme i bastun {0}C.", celsius);
            }
        }
        while (celsius < lowerTempLimit || celsius > upperTempLimit);
    }
S. Gunel
  • 13
  • 1
  • 6