views:

350

answers:

6

The program I've written is set to only accept positive integers as input. If the user inputs a letter instead, then it crashes. Negative integers don't cause any problems, though it's not 'valid' in regards to how my program functions.

What I want to do is:

  1. Prevent the program from crashing from invalid input.

  2. Display an error message if the input is invalid

  3. Have the program continue where it left off, without affecting the rest of the program.

Also, a part of my program involves division. Is there a way to prevent the user from entering all zeros?

This is in C#

My code:

using System;

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

namespace OverallCalculator {

class Program
{
    static void Main(string[] args)
    {
        bool shouldContinue;


        do
        {




            Console.WriteLine("Enter Striking Level: ");

            string striking = Console.ReadLine();

            Console.WriteLine("Enter Grappling Level: ");

            string grappling = Console.ReadLine();

            Console.WriteLine("Enter Submission Level: ");

            string submission = Console.ReadLine();

            Console.WriteLine("Enter Durability Level: ");

            string durability = Console.ReadLine();

            Console.WriteLine("Enter Technical Level: ");

            string technical = Console.ReadLine();

            Console.WriteLine("Enter Speed Level: ");

            string speed = Console.ReadLine();

            Console.WriteLine("Enter Hardcore Level: ");

            string hardcore = Console.ReadLine();

            Console.WriteLine("Enter Charisma Level: ");

            string charisma = Console.ReadLine();




            int gra = Convert.ToInt32(grappling);
            int str = Convert.ToInt32(striking);
            int dur = Convert.ToInt32(durability);
            int spd = Convert.ToInt32(speed);
            int tec = Convert.ToInt32(technical);
            int hdc = Convert.ToInt32(hardcore);
            int cha = Convert.ToInt32(charisma);
            int sub = Convert.ToInt32(submission);

            int total = str + gra + sub + dur + tec + spd + cha + hdc;


            int overall = total / 8 + 8;




            Console.WriteLine("The Overall is " + overall);
            Console.WriteLine("Do you wish to continue? y/n? ");



            if (Console.ReadLine() == "y")
            {
                shouldContinue = true;


            }
            else break;


        } while (shouldContinue == true);
    }
}

}

+3  A: 
int value = 0;
if (!int.TryParse(input, out value))
{
    MessageBox.Show("Oops");
} else {
    // use the value in the variable "value".
}
David Morton
Will this work if the program runs in the command line?
Slateboard
@Slateboard - the solution provided is fine except you would use Console.WriteLine("Oops") instead of MessageBox.Show()
David Hall
@David - did I misread the question, or should you be checking if TryParse is false in your example?
thedugas
@David Morton - agree with thedugas, your validation is backwards. I've taken the liberty of fixing your answer.
David Hall
@David Morton (my fellow Houstonian) - one more thing, if the valid input is only positive integers, it needs to be changed to an unsigned int as a negative will allow the TryParse on an int to return true.
thedugas
@David thanks. I overlooked that. @dugas: add another if statement, checking to see if value is greater than 0. I've updated the post for you.
David Morton
A: 

Yes... before you do anything calculations, you need to validate the data you are going to use. If any data is incorrect, then you display a messagebox detailing the errors and return focus to the form so the user can fix the errors. Repeat as necessary.

JDMX
A: 

I'm guessing that you're not at the stage to use other or create your own exception classes, so recommend doing something along these lines:

int var;

do
{
  cout << "\nInput please: "
  cin >> var;
}
while (typeid(var).name() != "int")

Note that "the typeid operator requires runtime type information (RTTI) to be generated, which must be explicitly specified at compile time through a compiler option." I'm not sure that the returned value is a string, but try it out and let me know!

tyblu
I don't think using typeid here is a good idea. If you want to know if the var was correctly read, then just test the truth value of cin itself. You loop would become `do { ... } while (!cin);`
Frank Krueger
Doesn't `var` get automatically typecast into a string if the input is such, which would be a valid input? I do tend to fk things up pretty often...
tyblu
var is an int - period. typeid(var) will always be "int". Also name() != "int" is not going to work, you mean strcmp
pm100
A: 

I wrote this one many moons ago when I first learned C#. It is a conversion from a VB function that I got back in VB5 days. The major benefit of the function is that there is no error - an input will just not allow any characters outside of the predefined list.

/***********************************************************************
 * bool ValiText(char inChar,
 *               string valid,
 *               bool editable,
 *               bool casesensitive
 * Description: Validate Input Characters As They Are Input
 * Notes: For each control whose input you wish to validate, just put
 *        e.Handled = ValiText(e.KeyChar, "0123456789/-" [,true][,true])
 *        In The KeyPress Event
 ***********************************************************************/
public bool ValiText(char inChar, string valid, bool editable, bool casesensitive)
{
    string inVal = inChar.ToString();
    string tst = valid;
    /// Editable - Add The Backspace Key
    if (editable) tst += ((char)8).ToString();
    /// Case InSensitive - Make Them Both The Same Case
    if (!casesensitive)
    {
        tst = tst.ToLower();
        inVal = inVal.ToLower();
    }
    return tst.IndexOf(inVal,0,tst.Length) < 0;
}
public bool ValiText(char inChar, string valid, bool editable)
{
    string tst = valid;
    /// Editable - Add The Backspace Key
    if (editable) tst += ((char)8).ToString();
    return tst.IndexOf(inChar.ToString(),0,tst.Length) < 0;
}
public bool ValiText(char inChar, string valid)
{
    return valid.IndexOf(inChar.ToString(),0,valid.Length) < 0;
}

Note That This Will Not Work On A Web APP.

Dave
+2  A: 
static void Main(string[] args)
{
        bool validInput = false;
        string inputString;
        UInt32 validPositiveInteger = 0;
        while (!validInput)
        {
            Console.WriteLine("Please enter a positive 32 bit integer:");
            inputString = Console.ReadLine();
            if (!UInt32.TryParse(inputString, out validPositiveInteger))
            {
                Console.WriteLine("Input was not a positive integer.");
            }
            else if (validPositiveInteger.Equals(0))
            {
                Console.WriteLine("You cannot enter zero.");
            }
            else
            {                   

                validInput = true;
                //Or you could just break
                //break;
            }


        }

        Console.WriteLine(String.Format("Positive integer = {0}", validPositiveInteger));
}
thedugas
+1 for giving a complete answer, including the positive requirement
David Hall
I modified the answer to include the check for zero.
thedugas
+1  A: 

Here you go:

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

namespace OverallCalculator
{
    class Program
    {
        static void Main(string[] args)
        {
            bool shouldContinue = true;

            while (shouldContinue)
            {
                int strikingLevel = GetValue("Enter Striking Level: ");
                int grapplingLevel = GetValue("Enter Grappling Level: ");
                int submissionLevel = GetValue("Enter Submission Level: ");
                int durabilityLevel = GetValue("Enter Durability Level: ");
                int technicalLevel = GetValue("Enter Technical Level: ");
                int speedLevel = GetValue("Enter Speed Level: ");
                int hardcoreLevel = GetValue("Enter Hardcore Level: ");
                int charismaLevel = GetValue("Enter Charisma Level: ");

                int total = strikingLevel + grapplingLevel + durabilityLevel + submissionLevel +
                    technicalLevel + speedLevel + charismaLevel + hardcoreLevel;

                int overall = total / 8 + 8;

                Console.WriteLine("\nThe Overall is {0}.", overall);
                while (true)
                {
                    Console.WriteLine("Do you wish to continue? y/n? ");
                    string response = Console.ReadLine();
                    if (response.Equals("y", StringComparison.CurrentCultureIgnoreCase) ||
                        response.Equals("yes", StringComparison.CurrentCultureIgnoreCase))
                    {
                        shouldContinue = true;
                        break;
                    }
                    else if (response.Equals("n", StringComparison.CurrentCultureIgnoreCase) ||
                        response.Equals("no", StringComparison.CurrentCultureIgnoreCase))
                    {
                        shouldContinue = false;
                        break;
                    }
                }
            } 
        }

        private static int GetValue(string prompt)
        {
            while (true)
            {
                Console.WriteLine(prompt);
                string input = Console.ReadLine();
                int value;
                if (int.TryParse(input, out value))
                {
                    if (value <= 0)
                        Console.WriteLine("Please enter a positive number.");
                    else
                        return value;
                }
                else
                {
                    Console.WriteLine("Please enter a number.");
                }
            }
        }
    }
}
Jeffrey L Whitledge
Thank you so much. Seeing the solution in my code makes it easier to understand.
Slateboard
You're welcome! Good luck!
Jeffrey L Whitledge