0

I got stuck with a small problem. I create a program where the user must to choose 5 options( 1.input numbers 2. Show smallest 3. Show Greatest 4. Display all numbers 5 Quit.) All the option are working. The problem is that when the user is choosing the option, if the press any letters is giving me error. I want that if the user is pressing any letter ori any symbol to be a warning message like "Unknown option value entered" and to try again. I suppose is about conversion or something similar, but i can't find where is the problem. Here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Assignmen2014_15
{
    class Program
    {
    const int MAXNUMBERS = 3;
        static void Main(string[] args)
        {
        int[] theNumbers = new int[MAXNUMBERS];
        int chosenOption = 0;
        bool quit = false;

        InitialiseNumbers(theNumbers);
        while (quit == false)
            {
            DisplayHeader();
            DisplayMenu();
            chosenOption = ReadNumber("Please choose an option: ");
            quit = ProcessMenu(chosenOption, theNumbers);
            Console.Clear();
            }
        }
        static void InitialiseNumbers(int[] numbers)
        {
            for (int index = 0; index < MAXNUMBERS; index++)
            {
            numbers[index] = 0;
            }
        }
        static void DisplayHeader()
        {
        WriteText("*******************************************************************************", 0, 0); // Top left hand corner of screen is x = 0, y = 0;
        WriteText("* This application is designed to allow you to choose numbers *", 0, 1); // Next line down is x = 0, y = 1, etc WriteText("* and finds the biggest and the smallest value *", 0, 2);
        WriteText("*******************************************************************************", 0, 3);
        }
        static void DisplayMenu()
        {
            WriteText("Select an option", 20, 8); // Display menu at at x = 20, y = 8
            WriteText("1. Enter the numbers", 20, 9);
            WriteText("2. Find the smallest", 20, 10);
            WriteText("3. Find the largest", 20, 11);
            WriteText("4. Display all numbers", 20, 12);
            WriteText("5. Quit", 20, 13);
        }
        static void WriteText(string text, int x, int y)
        {
            Console.CursorLeft = x;
            Console.CursorTop = y;
            Console.Write(text);
        }
        static int ReadNumber(string prompt)
        {
            string text;
            int number;
            WriteText(prompt, 20, 14);
            text = Console.ReadLine();
            number = int.Parse(text);
            ClearText(20, 14, prompt.Length + text.Length); // Clear the text at this line
            return number;

        }
        static void ClearText(int x, int y, int length)
        {
            // Write space ' ' characters starting at x, y for 'length' times
            WriteText(new String(' ', length), x, y);
        }

        static void DisplayNumbers(int[] theNumbers)
        {
            Console.Write("Your numbers are: ");
            for (int i = 0; i < MAXNUMBERS; i++)
            {
                Console.WriteLine(theNumbers[i]);
            }

        }

        static bool ProcessMenu(int option, int[] numbers)
        {
            bool quit = false;

            switch (option)
            {
                case 1:
                    GetNumbers(numbers);
                    break;
                case 2:
                    WriteText(string.Format("The smallest value is {0}", FindSmallest(numbers)), 20, 15);
                    Console.ReadKey(); // Pause
                    break;
                case 3:
                    WriteText(string.Format("The largest value is {0}", FindLargest(numbers)), 20, 15);
                    Console.ReadKey(); // Pause
                    break;
                case 4:
                    DisplayNumbers(numbers);
                    Console.ReadKey();
                    break;
                case 5:
                    quit = IsQuitting();
                    break;
                default:
                    WriteText("Unknown option value entered", 20, 15);
                    Console.ReadKey(); // Pause 
                    break;
            }
            return quit;
        }
        static void GetNumbers(int[] numbers)
        {
            for (int index = 0; index < MAXNUMBERS; index++)
            {
                numbers[index] = ReadNumber("Enter number: ");
            }
        }
        static int FindSmallest(int[] numbers)
        {
            int smallest = numbers[0];
            for (int index = 0; index < MAXNUMBERS - 1; index++) // <-- subtract 1
            {
                if (numbers[index + 1] < smallest)
                {
                    smallest = numbers[index + 1];
                }
            }
            return smallest;
        }
        static int FindLargest(int[] numbers)
        {
            int largest = numbers[0];
            for (int index = 0; index < MAXNUMBERS - 1; index++) // <-- subtract 1
            {
                if (numbers[index + 1] > largest)
                {
                    largest = numbers[index + 1];
                }
            }
            return largest;
        }
        static bool IsQuitting()
        {
            string response;
            bool quit = false;
            WriteText("Do you really wish to quit? ", 20, 13);
            response = Console.ReadLine();
            if (response.Equals("Yes" , StringComparison.InvariantCultureIgnoreCase) || response.Equals("Y", StringComparison.InvariantCultureIgnoreCase))
            {
                quit = true;
            }
            return quit;
        }
    }
}
slugster
  • 49,403
  • 14
  • 95
  • 145
Bogdanho
  • 43
  • 4
  • Use `int.TryParse` instead of `int.Parse` – Kalten Jan 06 '19 at 22:34
  • is not working! – Bogdanho Jan 06 '19 at 22:36
  • 1
    You should add to your question the error you get. And where it's not working – Kalten Jan 06 '19 at 22:39
  • You should always use Try-Catch concepts when programming with user inputs as part of your program. – M.Hazara Jan 06 '19 at 22:40
  • Unhandled Exception: System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) at System.Int32.Parse(String s) at Assignmen2014_15.Program.ReadNumber(String prompt) in C:\Users\bogda\source\repos\appendix\appendix\Program.cs:line 62 at Assignmen2014_15.Program.Main(String[] args) in C:\Users\bogda\source\repos\appendix\appendix\Program.cs:line 23 – Bogdanho Jan 06 '19 at 22:40
  • Possible duplicate of [Parse v. TryParse](https://stackoverflow.com/questions/467613/parse-v-tryparse) – mjwills Jan 06 '19 at 22:44
  • 1
    Please do not clarify your question here in the comments. If your question needs to be clarified/expanded, **edit** and improve the question itself. (A side note for future questions: dumping the _whole_ program code into the question is seldomly beneficial. Only provide as much code as _necessary_ to illustrate and/or reproduce the problem. See here: [mcve]) –  Jan 06 '19 at 22:51

1 Answers1

1

Use Int32.TryParse(String, Int32) method which tries to parse string into integer and returns boolean value representing if parsing was successful or not. In your case, if parsing fails, you can return -1 from your ReadNumber method which will call default: part of your switch case and an error message will be displayed. Otherwise, if parsing was successful, you can simply return the parsed number, which will be either be one of your desired numbers or it will call default: action.

The following is example from Microsoft documentation

String[] values = { null, "160519", "9432.0", "16,667",
                      "   -322   ", "+4302", "(100);", "01FA" };
foreach (var value in values) 
{
   int number;

   bool success = Int32.TryParse(value, out number);
   if (success)
   {
      Console.WriteLine("Converted '{0}' to {1}.", value, number);         
   }
   else
   {
      Console.WriteLine("Attempted conversion of '{0}' failed.", 
                         value ?? "<null>");
   }
}

In your specific example you need to modify your ReadNumber(string prompt) method:

static int ReadNumber(string prompt)
{
    string text;
    int number;
    WriteText(prompt, 20, 14);
    text = Console.ReadLine();
    bool is_parsing_successful = Int32.TryParse(text, out number);
    ClearText(20, 14, prompt.Length + text.Length); // Clear the text at this line
    if(is_parsing_successful){
        return number;
    } else {
        return -1;
    }
}
rCgLT
  • 128
  • 6
  • still same problem. If i press a when should I choose on number between 1 and 5 is giving me an error – Bogdanho Jan 06 '19 at 22:54
  • if i chose for example 6 ( which is out of area is warning me that is unkown value) but if i type a or any text is error – Bogdanho Jan 06 '19 at 22:55
  • Edited the code. Forgot 'out' keyword in TryParse statement. Try it now. – rCgLT Jan 06 '19 at 22:59