Hey, all I am currently doing an assignment and I am having a tough time with managing my output. What I am trying to do is that when the program ends it asks the user if they would want to try again if yes it loops back to the beginning if no it exits. So my problem here is whenever I loop back to the beginning the output gets destroyed. I am a beginner programmer, and it is just now I've tried C# (I came from C++). I think the problem is coming from my console.writeline(), I think it leaves a phantom character(? not sure) like in c++'s getline(). The following snippets are my main class and the abstract data type that I created.

//THIS IS MY MAIN
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FeeComputation_Adina
{
    class FeeComputation
    {
        static void Main(string[] args)
        {

            string nameFirst, nameLast, course;
            char gender, nameMI, doReload;
            int year, unitsLec, unitsLab;
            bool isGenderInCorrect = true, isInCorrectLoad = true, isYLVLInCorrect = true, isInCorrectChoice = true, isReload = true;
            callIntroMessage();

            do
            {
                
                callTitle();
                callStudentInfoHeader();
                Console.Write("\t\t\tEnter Last Name: "); nameLast = Convert.ToString(Console.ReadLine());
                Console.Write("\t\t\tEnter First Name: "); nameFirst = Convert.ToString(Console.ReadLine());
                Console.Write("\t\t\tEnter Middle Initial: "); nameMI = Convert.ToChar(Console.ReadLine());
                do
                {

                    Console.Write("\t\t\tEnter Gender [M/F]: "); gender = Convert.ToChar(Console.ReadLine());

                    if ((gender == 'm') || (gender == 'M') || (gender == 'F') || (gender == 'f'))
                    {
                        isGenderInCorrect = false;
                    }

                    else
                    {
                        Console.Clear();
                        Console.WriteLine("You have input an incorrect gender.");
                        Console.WriteLine("Correct choices are: 'F' for female and 'M' for male, please try again.");
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        isGenderInCorrect = true;
                    }
                    callTitle();
                    callStudentInfoHeader();
                    Console.WriteLine("\t\t\tEnter Last Name: " + nameLast);
                    Console.WriteLine("\t\t\tEnter First Name: " + nameFirst);
                    Console.WriteLine("\t\t\tEnter Middle Initial: " + nameMI);
                }
                while (isGenderInCorrect);
                Console.Clear();

                callTitle();
                callDegreeYearHeader();
                Console.Write("\t\t\tEnter Degree Program: "); course = Convert.ToString(Console.ReadLine());
                do
                {
                    Console.Write("\t\t\tEnter Current Year Level: "); year = Convert.ToInt32(Console.ReadLine());

                    if ((year < 1) || (year > 5))
                    {
                        Console.Clear();
                        Console.WriteLine("You have input an incorrect year level.");
                        Console.WriteLine("Year level ranges only from 1 to 5, please try again.");
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        isYLVLInCorrect = true;
                    }

                    else if ((year >= 1) && (year <= 5))
                    {
                        isYLVLInCorrect = false;
                    }
                    callTitle();
                    callDegreeYearHeader();
                    Console.WriteLine("\t\t\tEnter Degree Program: " + course);

                }
                while (isYLVLInCorrect);
                Console.Clear();

                do
                {
                    callTitle();
                    callLabLecUnitHeader();
                    Console.Write("\t\t   Enter Currently Enrolled Lecture Units: "); unitsLec = Convert.ToInt32(Console.ReadLine());
                    Console.Write("\t\t   Enter Currently Enrolled Laboratory Units: "); unitsLab = Convert.ToInt32(Console.ReadLine());
          
                    if ((unitsLec + unitsLab) < 12)
                    {
                        Console.Clear();
                        Console.WriteLine("You have made an error.");
                        Console.WriteLine("The total number of units inccured is only " + (unitsLec + unitsLab) + (" unit(s)."));
                        Console.WriteLine(); Console.WriteLine();
                        Console.WriteLine("This means the student is UNDERLOADED.");
                        Console.WriteLine("Please input the correct number of units to fix this problem.");
                        Console.WriteLine(); Console.WriteLine();
                        Console.WriteLine("Please note that the MINIMUM number of units allowed is only 12.");
                        Console.WriteLine(); Console.WriteLine();
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        isInCorrectLoad = true;
                    }

                    else if ((unitsLec + unitsLab) > 18)
                    {
                        Console.Clear();
                        Console.WriteLine("You have made an error.");
                        Console.WriteLine("The total number of units inccured is " + (unitsLec + unitsLab) + (" units."));
                        Console.WriteLine(); Console.WriteLine();
                        Console.WriteLine("This means the student is OVERLOADED.");
                        Console.WriteLine("Please input the correct number of units to fix this problem.");
                        Console.WriteLine(); Console.WriteLine();
                        Console.WriteLine("Please note that the MAXIMUM number of units allowed is only 18.");
                        Console.WriteLine(); Console.WriteLine();
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        isInCorrectLoad = true;
                    }

                    else if (((unitsLec + unitsLab) <= 18) && ((unitsLec + unitsLab) >= 12))
                    { 
                        isInCorrectLoad = false; 
                    }
                } 
                while (isInCorrectLoad);
                Console.Clear();

                StudentTuitionFee studentInfo = new StudentTuitionFee(nameFirst, nameMI, nameLast, gender, course, year);

                displayBreakDown(studentInfo, unitsLec, unitsLab, gender, nameFirst, nameMI, nameLast, course, year);

                Console.Clear();
                Console.Write("Would you like to compute the tuition fee for a different student? [Y/N]: "); //TRY MAKING THIS A COMMENT AND IT WILL RUN SMOOTHLY
                doReload = Convert.ToChar(Console.Read());
                Console.Write("Press any key to continue . . .");
                Console.ReadKey();
                Console.Clear();

                do
                {
                    if ((doReload == 'y') || (doReload == 'Y'))
                    {
                        isInCorrectChoice = false;
                        isReload = true;
                      
                    }

                    else if ((doReload == 'n') || (doReload == 'N'))
                    {
                        isInCorrectChoice = false;
                        isReload = false;
                        Console.WriteLine(); Console.WriteLine();
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey();
                    }

                    else if ((doReload == 'y') || (doReload == 'Y') || (doReload != 'n') || (doReload != 'N'))
                    {
                        Console.Clear();
                        Console.WriteLine("You have input an incorrect choice.");
                        Console.WriteLine("Answer choices are only 'Y' for yes and 'N' for no, please try again.");
                        Console.WriteLine("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        isInCorrectChoice = true;
                        isReload = true;
                    }
                }
                while (isInCorrectChoice);
            }
            while (isReload);
        }

        static void callTitle()
        {
            Console.WriteLine("  xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx");
            Console.WriteLine("x                                                                             x");
            Console.WriteLine("X                                                                             X");
            Console.WriteLine("x                      Basic Tuition Fee Calculator v1.00                     x");
            Console.WriteLine("X                                                                             X");
            Console.WriteLine("x                                                                             x");
            Console.WriteLine("  xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx");
            Console.WriteLine(); Console.WriteLine();
        }

        static void callStudentInfoHeader()
        {
            Console.WriteLine("  oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOo");
            Console.WriteLine("O                                                                             O");
            Console.WriteLine("o                                                                             o");
            Console.WriteLine("O                           Student Name and Gender                           O");
            Console.WriteLine("o                                                                             o");
            Console.WriteLine("O                                                                             O");
            Console.WriteLine("  oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOo");
            Console.WriteLine(); Console.WriteLine();
        }

        static void callDegreeYearHeader()
        {
            Console.WriteLine("  oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOo");
            Console.WriteLine("O                                                                             O");
            Console.WriteLine("o                                                                             o");
            Console.WriteLine("O                            Degree and Year Level                            O");
            Console.WriteLine("o                                                                             o");
            Console.WriteLine("O                                                                             O");
            Console.WriteLine("  oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOo");
            Console.WriteLine(); Console.WriteLine();
        }

        static void callLabLecUnitHeader()
        {
            Console.WriteLine("  oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOo");
            Console.WriteLine("O                                                                             O");
            Console.WriteLine("o                                                                             o");
            Console.WriteLine("O                    Laboratory and Lecture Units Enrolled                    O");
            Console.WriteLine("o                                                                             o");
            Console.WriteLine("O                                                                             O");
            Console.WriteLine("  oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOo");
            Console.WriteLine(); Console.WriteLine();
        }

        static void callIntroMessage()
        {
            callTitle();
            Console.WriteLine("  xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx");
            Console.WriteLine("x                                                                             x");
            Console.WriteLine("X         Welcome! This is a simple tuition fee calculator that will          X");
            Console.WriteLine("x         accept proper input from the user and compute for the tui-          x");
            Console.WriteLine("X         tion fee of a student with respect to their gender and out-         X");
            Console.WriteLine("x         put a properly tabulated matriculation of fees.                     x");
            Console.WriteLine("x                                                                             x");
            Console.WriteLine("x         Press any key to continue!                                          x");
            Console.WriteLine("x                                                                             x");
            Console.WriteLine("  xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx");
            Console.ReadKey(); Console.Clear();
        }

      
        
        static void displayBreakDown(StudentTuitionFee studentInfo, int unitsLec, int unitsLab, char gender, string nameFirst, char nameMI, string nameLast, string course, int year)
        {
            callTitle();
            Console.WriteLine();
            Console.WriteLine(studentInfo.getLectureUnitFee(unitsLec));
            Console.WriteLine(studentInfo.getLabUnitFee(unitsLab));
            Console.WriteLine(studentInfo.getTotalUnitFee(unitsLec, unitsLab));
            Console.WriteLine(studentInfo.getTotalTuitionFee(unitsLec, unitsLab, gender));
            Console.WriteLine(studentInfo.getTotalMiscFee(gender));
            Console.WriteLine(nameFirst + nameMI + nameLast + gender);
            Console.WriteLine(course + year);
            Console.WriteLine(unitsLab + unitsLec);
            Console.WriteLine(); Console.WriteLine();
            Console.Write("Press any key to continue . . .");
            Console.ReadKey();
        }

    }
}
//THIS IS MY ABSTRACT DATA TYPE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FeeComputation_Adina
{
    class StudentTuitionFee
    {
        const double feeINTER = 2500.00, feeID = 150.00, feeSCDL = 100.00, feeHBOOK = 230.00, feeROTC = 1500.00, perUnitFee = 748.00;
        string studentFirstName, studentLastName, studentCourse;
        char studentMI, studentGender;
        int studentCourseYear;



        public StudentTuitionFee(string FN, char MI, string LN, char gender, string course, int yearLevel)
        {
            studentFirstName = FN;
            studentMI = MI;
            studentLastName = LN;
            studentGender = gender;
            studentCourse = course;
            studentCourseYear = yearLevel;
        }

        public double getLectureUnitFee(int unitsLecture)
        {
            return perUnitFee * unitsLecture;
        }

        public double getLabUnitFee(int unitsLaboratory)
        {
            return perUnitFee * unitsLaboratory;
        }

        public double getTotalUnitFee(int unitsLecture, int unitsLaboratory)
        {
            return ((unitsLecture + unitsLaboratory) * perUnitFee);
        }

        public double getTotalTuitionFee(int unitsLecture, int unitsLaboratory, char studGender)
        {
            if ((studGender == 'm') || (studGender == 'M'))
            {
                return (feeINTER + feeID + feeROTC + feeSCDL + ((unitsLaboratory + unitsLecture) * perUnitFee));
            }

            else if ((studGender == 'f') || (studGender == 'F'))
            {
                return (feeINTER + feeID + feeSCDL + ((unitsLaboratory + unitsLecture) * perUnitFee));
            }
            else
            {
                return 0;
            }
        }

        public double getTotalMiscFee(char studGender)
        {
            if ((studGender == 'm') || (studGender == 'M'))
            {
                return (feeINTER + feeID + feeROTC + feeSCDL);
            }

            else if ((studGender == 'f') || (studGender == 'F'))
            {
                return (feeINTER + feeID + feeSCDL);
            }
            else
            {
                return 0;
            }
        }
    }
}

I have not implemented any data hiding for my professor told us not to do so yet. I also asked him if I should create a destructor and he just said that garbage collector should do the job for me, but my problem is when I loop I THINK I can't rely with garbage collector.

Also, what is better parse or convert.to? I find them the same but some of my peers say parse is better than convert.to because it has exception handling (but, as I have read convert.to also has that).

Thanks to those who'll be reading this and replying! Thank you so much!

What exactly do you mean by "my output gets destroyed"?
I see a lot of Console.Clear() in your code. This method erases anything you already wrote to the console.
I don't see why your class StudentTuitionFee is abstract, I don't see an abstarct keyword. To me and the C# compiler this looks like a private class.

What exactly do you mean by "my output gets destroyed"?
I see a lot of Console.Clear() in your code. This method erases anything you already wrote to the console.
I don't see why your class StudentTuitionFee is abstract, I don't see an abstarct keyword. To me and the C# compiler this looks like a private class.

What I meant was the format of how my text gets displayed gets distorted.

For example, in the first run it looks like this:

Enter Last Name:
Enter First Name:
.
.
.
And so on.

But on the second run, after it loops, it looks like this:

Enter Last Name: Enter First Name:

The enter last name part gets covered up by my enter first name part and thus I can't access it so that I could write another name.

Oh so that's what it's called, I'm sorry sir, I thought that if I created a class of my own (or data type?) I could call it an abstract data type. Deeply sorry.

Oh so that's what it's called, I'm sorry sir, I thought that if I created a class of my own (or data type?) I could call it an abstract data type. Deeply sorry.

An abstract class is a class that is not meant to be instantiated on its own but rather is a base for another class. It is declared like this:

public abstract class MyBase
{
}

And then a derived type can inherit from it.

public class MyDerived : MyBase
{
}

An abstract class can define methods and properties, either as abstract themselves or with implementations. If the methods or properties are abstract, the derived type has to implement them, much like an interface. Of course, if there is an inheritance chain involved, such that B inherits A and C inherits B, then B does not have to implement A's abstract methods or properties as long as B is abstract, as well. Anything not implemented by B would be the responsibility of C.

The problem stems from the 'nameLast = Convert.ToString(Console.ReadLine());' being passed over/not processed on the second loop. I tracked the source down to the line in the code below. By using ReadLine isntead of Read it fixes the problem. I am not entirely sure why this is though. Perhaps someone more experienced can shed some light on this. I'd love to know why the linefeed is carrying over into the next ReadLine() : /

Console.Write("Would you like to compute the tuition fee for a different student? [Y/N]: ");
                doReload = Convert.ToChar(Console.ReadLine()); //fixed here

Edited 6 Years Ago by Geekitygeek: n/a

An abstract class is a class that is not meant to be instantiated on its own but rather is a base for another class. It is declared like this:

public abstract class MyBase
{
}

And then a derived type can inherit from it.

public class MyDerived : MyBase
{
}

An abstract class can define methods and properties, either as abstract themselves or with implementations. If the methods or properties are abstract, the derived type has to implement them, much like an interface. Of course, if there is an inheritance chain involved, such that B inherits A and C inherits B, then B does not have to implement A's abstract methods or properties as long as B is abstract, as well. Anything not implemented by B would be the responsibility of C.

Oh, so an abstract data type is the err 'father' and is the one based from to create his err 'son'. Properties (data types in the class(?)) and methods (functions in the class(?)) are derived from the father and also the methods. Did I get it sir?

I did not quite get this part: "If the methods or properties are abstract, the derived type has to implement them, much like an interface." and also the parts after that. Can you site an example if possible sir?

The problem stems from the 'nameLast = Convert.ToString(Console.ReadLine());' being passed over/not processed on the second loop. I tracked the source down to the line in the code below. By using ReadLine isntead of Read it fixes the problem. I am not entirely sure why this is though. Perhaps someone more experienced can shed some light on this. I'd love to know why the linefeed is carrying over into the next ReadLine() : /

Console.Write("Would you like to compute the tuition fee for a different student? [Y/N]: ");
                doReload = Convert.ToChar(Console.ReadLine()); //fixed here

Nice, thank you very much Ryshad! I hope someone do shed light on this one, I was pretty much dumbfounded by this one. D:

I tried implementing try catch and worked fine too:

//snippet

do
                {
                    try
                    {
                        Console.Write("Would you like to compute the tuition fee for a different student? [Y/N]: "); doReload = Char.Parse(Console.ReadLine());

                        if ((doReload == 'y') || (doReload == 'Y'))
                        {
                            isInCorrectChoice = false;

                        }

                        else if ((doReload == 'n') || (doReload == 'N'))
                        {
                            isInCorrectChoice = false;
                            isReload = false;
                            Console.Write("Press any key to continue . . .");
                            Console.ReadKey();
                        }

                        else
                        {
                            Console.Clear();
                            Console.WriteLine("You have input an incorrect choice.");
                            Console.WriteLine("Answer choices are only 'Y' for yes and 'N' for no, please try again.");
                            Console.Write("Press any key to continue . . .");
                            Console.ReadKey(); Console.Clear();
                        }
                    }

                    catch
                    {
                        Console.Clear();
                        Console.WriteLine("You have input an incorrect choice.");
                        Console.WriteLine("Answer choices are only 'Y' for yes and 'N' for no, please try again.");
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                    }
             
                }
                while (isInCorrectChoice);

My problem now is, when I tried applying that in other parts of my code, I get compiler errors that result from my initial values not being updated when the user inputs their values.

Here is a part of my code where I think where the problem starts from:

//snippet
do
                {
                    try
                    {
                        Console.Write("\t\t\tEnter Gender [M/F]: "); gender = Char.Parse(Console.ReadLine());
                        if ((gender == 'm') || (gender == 'M') || (gender == 'f') || (gender == 'F'))
                        {
                            isGenderInCorrect = false;
                            
                        }

                        else
                        {
                            Console.Clear();
                            Console.WriteLine("You have input an incorrect choice.");
                            Console.WriteLine("Answer choices are only 'Y' for yes and 'N' for no, please try again.");
                            Console.Write("Press any key to continue . . .");
                            Console.ReadKey(); Console.Clear();
                            callTitle();
                            callStudentInfoHeader();
                            Console.WriteLine("\t\t\tEnter Last Name: " + nameLast);
                            Console.WriteLine("\t\t\tEnter First Name: " + nameFirst);
                            Console.WriteLine("\t\t\tEnter Middle Initial: " + nameMI);
                        }
                    }

                    catch
                    {
                        Console.Clear();
                        Console.WriteLine("You have input an incorrect choice.");
                        Console.WriteLine("Answer choices are only 'Y' for yes and 'N' for no, please try again.");
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        callTitle();
                        callStudentInfoHeader();
                        Console.WriteLine("\t\t\tEnter Last Name: " + nameLast);
                        Console.WriteLine("\t\t\tEnter First Name: " + nameFirst);
                        Console.WriteLine("\t\t\tEnter Middle Initial: " + nameMI);
                    }

                }
                while (isGenderInCorrect);

So the problem now is gender's updated value does not get out of the try catch block (or maybe the do while loop?) and thus when I (instantiate(?)) do this:

//snippet
StudentTuitionFee studentInfo = new StudentTuitionFee(nameFirst, nameMI, nameLast, gender, course, year);

It says that the gender parameter was not updated, and thus is implied as a: "Use of unassigned local variable 'gender' " compiler error.

But if I place the

Console.Write("\t\t\tEnter Gender [M/F]: "); gender = Char.Parse(Console.ReadLine());

part out of the try catch block it works, although when I try inputting a string or numbers in it, it crashes! Not unlike the previous try catch block above that I made which accepts any value and does not crash =(

Edited 6 Years Ago by ticktock: n/a

Okaaaay, just made a work around for that pesky gender checking part of my code, it looks like err brute forced, comments are appreciated:

//snippet


                do
                {
                    
                    Console.Write("\t\t\tEnter Gender [M/F]: "); checkGenderInput = Convert.ToString(Console.ReadLine());
                    if ((checkGenderInput == "m") || (checkGenderInput == "M") || (checkGenderInput == "f") || (checkGenderInput == "F"))
                    {
                        isGenderInCorrect = false;
                        

                    }

                    else
                    {
                        Console.Clear();
                        Console.WriteLine("You have input an incorrect choice.");
                        Console.WriteLine("Answer choices are only 'Y' for yes and 'N' for no, please try again.");
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        callTitle();
                        callStudentInfoHeader();
                        Console.WriteLine("\t\t\tEnter Last Name: " + nameLast);
                        Console.WriteLine("\t\t\tEnter First Name: " + nameFirst);
                        Console.WriteLine("\t\t\tEnter Middle Initial: " + nameMI);
                    }
                    
                }
                while (isGenderInCorrect);
                gender = Convert.ToChar(checkGenderInput);

What i did was accept an input using a variable of type string, check the input if it corresponds to the correct one. If it does exit the loop and then type cast the string to a char, and if it doesn't the loop, loops back and asks for another input. It works, but it looks kinda sloppy to me.

The error with the unassigned local variable is a result of placing the assignent inside the try catch block.
If all code paths do not return a value then the error will be thrown. The error here isnt that you never assign a value, its that a path of execution could result in you trying to access a variable that doesnt exist. When you declare the variable, you dont assign it a value. Your assignment occurs inside a try..catch block. If you were to assign the variable a 'default' value either when declaring it or by adding a ..finally block to your try..catch then you could be sure that all paths result in a value being stored.

Also, you may want to look at some guides on exception handling. Generally you put the try{} around the specific piece of code you feel might throw an exception then handle the situations where the exception occurs in the catch block.

I did not quite get this part: "If the methods or properties are abstract, the derived type has to implement them, much like an interface." and also the parts after that. Can you site an example if possible sir?

An interface is an empty shell that defines methods and properties with no implementations. Classes that inherit from these interfaces must provide the implementations, or else the code will not compile. You cannot create an instance of an interface.

An abstract class is similar, you cannot create an instance of it and it can have abstract methods and properties that a derived class must implement. The difference is that an abstract can also have methods and properties with implementations.

Here's a code example.

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

            DerivedType derived = new DerivedType();
            derived.DoSomething();
            derived.DoSomethingElse();

            Console.Read();
        }
    }

    public abstract class BaseType
    {
        public abstract void DoSomething(); 
        // declares an abstract method of type void called DoSomething.
        // abstract methods have no implementations in the base class,
        // they must be implemented by a non-abstract derived class

        public void DoSomethingElse()
        {
            Console.WriteLine("Doing something else from the base type.");
        }
    }

    public class DerivedType : BaseType
    {
        public override void DoSomething()
        {
            // this is where you define the implementation for the 
            // base class' DoSomething method.
            Console.WriteLine("Doing something from the derived type.");
        }
    }

I also mentioned an inheritance chain. There can be an abstract base class (with abstract methods or properties) that is inherited by another abstract class. This second abstract class does not have to implement the abstract methods and properties of the base. This class cannot be instantiated, either, it would be up to a class further down the chain that is non-abstract to ensure that all the implementations are in place. Further, the second abstract class can define still more abstract methods and properties, all becoming the responsibility of the non-abstract class down the chain.

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

            DerivedType derived = new DerivedType();
            derived.DoSomething();
            derived.DoSomethingElse();

            Console.Read();
        }
    }

    public abstract class BaseType
    {
        public abstract void DoSomething(); 
    }

    public abstract class MiddleDerivedType : BaseType
    {
        public abstract void DoSomethingElse();
    }

    public class DerivedType : MiddleDerivedType 
    {
        public override void DoSomething()
        {
            Console.WriteLine("Implementing BaseType's DoSomething() method.");
        }

        public override void DoSomethingElse()
        {
            Console.WriteLine("Implementing MiddleDerivedType's DoSomethingElse() method.");
        }
    }

You were starting along the right lines, the crash occurs when you try to char.parse an invalid string. You can only read a single character into a char.
Any time you accept input from a user you must anticipate and handle invalid input. You can do this by manually checking for errors, or by using exception handling.
If you wanted to use exception handling it would look something like:

Console.Write("\t\t\tEnter Gender [M/F]: ");

                    try
                    {
                        gender = Convert.ToChar(Console.ReadLine());
                    }
                    catch(FormatException)
                    {
                        gender = 'a';
                    }

                    if ( ((gender == 'm') || (gender == 'f')))
                    ....

You try reading in the value, if an error occurs you assign a default value.
An easier way would be to use the char.tryparse method. The tryparse method attempts to convert a string to a char and store it in the given variable. It returns a boolean to determine if the parse was successful.

Heres how to implement it in your code:

Console.Write("\t\t\tEnter Gender [M/F]: "); //gender = Convert.ToChar(Console.ReadLine());

                    if (char.TryParse(Console.ReadLine().ToLower(), out gender) && ((gender == 'm') || (gender == 'f')))
                    {
                        isGenderInCorrect = false;
                    }
                    ...

Also, i added the ToLower() method which converts the input string into lower case, removing the requirement to test for both the upper and lower case matches :)

Edited 6 Years Ago by Geekitygeek: n/a

@Ryshad:

What does TryParse and out do?

@apegram:

Thank you for the lengthy explanation! I am currently in the process of understanding it. Comments later haha.

TryParse will return true/false if the parse is successful. The "out" variable is the result of the actual parsing. It's available across int, double, datetime, etc.

string input = "15";
int output = 0;
bool isInteger = int.TryParse(input, out output);

// isInteger will be true, output will be 15

input = "15a";
output = 0;
isInteger = int.TryParse(input, out output);

// isInteger will be false, output will be 0;

It's useful because other methods (Convert.ToX, x.Parse) will throw exceptions if there are invalid inputs. Which is fine, you can catch the exception and do whatever you want, but is inefficient overall. TryParse can give you a true/false execution path and still allow you to handle invalid inputs.

On the "out" keyword specifically, it is an alternate syntax for passing a variable by reference except that it requires the method that receives it to set a value to it before returning. Normally, value types are passed by value, so you can manipulate that value all day long in a method, but the original variable in the calling method will not be modified. Passing by reference (ref or out keyword) passes the reference to the variable instead of the value, so any modifications in the callee will be reflected in the variable in the caller.

Edited 6 Years Ago by apegram: n/a

@apegram:

so the part in the if statement where it says "out gender" is kinda like gender = whatever was typed in, is that correct?

@apegram:

so the part in the if statement where it says "out gender" is kinda like gender = whatever was typed in, is that correct?

If whatever was typed in is a character, yes.

string input = "aa";
            char c;
            Char.TryParse (input, out c);
            Console.WriteLine("First attempt: {0}", c);

            input = "a";
            char.TryParse(input, out c);
            Console.WriteLine("Second attempt: {0}", c);

            Console.Read();

In this example, the first time, c will be empty. Test it and see.

Edited 6 Years Ago by apegram: n/a

If whatever was typed in is a character, yes.

string input = "aa";
            char c;
            Char.TryParse (input, out c);
            Console.WriteLine("First attempt: {0}", c);

            input = "a";
            char.TryParse(input, out c);
            Console.WriteLine("Second attempt: {0}", c);

            Console.Read();

In this example, the first time, c will be empty. Test it and see.

Thank you very much for your sample! I have finished the whole program!

I utilized try parse and for some of my error handling processes, while for the others I used simple if else and looping statements.

Here are some samples:

For the middle initial input part of my code I checked if the user inputs anything that is more than 2 characters long it is automatically an error. This is because middle initials (as far as I know) consists of only one character.

And I also used an if else statement that checks if a character entered is not a symbol or number. I did this through the utilization of the ascii numbers of letters.

//snippet

do //DO WHILE LOOP THAT ACCEPTS AND HANDLES ERRORS FOR THE MIDDLE INITIAL PART OF THE INPUT
                {

                    Console.Write("\t\t\tEnter Middle Initial: "); checkMIInput = Convert.ToString(Console.ReadLine());

                    if (checkMIInput.Length > 1)
                    {
                        Console.Clear();
                        Console.WriteLine("You have input an incorrect parameter.");
                        Console.WriteLine("Middle initials are only of one character length.");
                        Console.WriteLine("They also consist of letters from a to z only.");
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        callTitle();
                        callStudentInfoHeader();
                        Console.WriteLine("\t\t\tEnter Last Name: " + nameLast);
                        Console.WriteLine("\t\t\tEnter First Name: " + nameFirst);

                    }

                    else if (checkMIInput.Length == 1)
                    {
                        char MI = char.Parse(checkMIInput);
                        if (((int)MI >= 65) && ((int)MI <= 90) || (((int)MI >= 97) && ((int)MI <= 122)))
                        {
                            isMIInCorrect = false;
                        }
                     
                        else
                        {
                            Console.Clear();
                            Console.WriteLine("You have input an incorrect parameter.");
                            Console.WriteLine("Middle initials are only of one character length.");
                            Console.WriteLine("They also consist of letters from a to z only.");
                            Console.Write("Press any key to continue . . .");
                            Console.ReadKey(); Console.Clear();
                            callTitle();
                            callStudentInfoHeader();
                            Console.WriteLine("\t\t\tEnter Last Name: " + nameLast);
                            Console.WriteLine("\t\t\tEnter First Name: " + nameFirst);
                        }
                    }
                }
                while (isMIInCorrect);
                nameMI = Convert.ToChar(checkMIInput);

For this part I just scanned the first 2 characters of the string if whether it was a BS or a BA major. I limited the input for the first two slots in the string to bs and ba because err that's the only two major programs that I know off hehe.

onsole.Write("\t\t\tEnter Degree Program: "); checkCourseInput = Convert.ToString(Console.ReadLine());

                    if ((checkCourseInput[0] == 'b') || (checkCourseInput[0] == 'B'))
                    {
                        if ((checkCourseInput[1] == 'a') || (checkCourseInput[1] == 'A') || (checkCourseInput[1] == 's') || (checkCourseInput[1] == 'S'))
                        {
                            isCourseInCorrect = false;
                        }

                        else
                        {
                            Console.Clear();
                            Console.WriteLine("You have input an incorrect parameter.");
                            Console.WriteLine("Degree programs start only with BS [Bachelor of Science] or");
                            Console.WriteLine("BA [Bachelor of Arts].");
                            Console.Write("Press any key to continue . . .");
                            Console.ReadKey(); Console.Clear();
                            callTitle();
                            callDegreeYearHeader();
                        }
                    }

                    else
                    {
                        Console.Clear();
                        Console.WriteLine("You have input an incorrect parameter.");
                        Console.WriteLine("Degree programs start only with BS [Bachelor of Science] or");
                        Console.WriteLine("BA [Bachelor of Arts].");
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        callTitle();
                        callDegreeYearHeader();
                    } 
                }
                while (isCourseInCorrect);
                course = Convert.ToString(checkCourseInput);

And here in this part, I think I kind of brute forced it again. I tried placing both try.parse in one if statement but I get that unassigned value error again so a work around that I thought of was first ask for the first part of the input and then errr somehow 'concatenate' the preceding outputs before I ask for the second part of the input so in that way I won't get errors.

do //DO WHILE LOOP THAT CHECKS AND HANDLES ERRORS IF THE USER HAS INPUT AN INVALID
                {  //ACCUMULATED ENROLLED UNITS COUNT
                    do //DO WHILE LOOP THAT CHECKS AND HANDLES ERRORS FOR THE LECTURE UNITS INPUT PART
                    {
                        callTitle();
                        callLabLecUnitHeader();
                        Console.Write("\t\t   Enter Currently Enrolled Lecture Units: "); checkLecUnits = Convert.ToString(Console.ReadLine());

                        if (Int32.TryParse(checkLecUnits, out unitsLec))
                        {
                            isInCorrectLecLoad = false;
                        }

                        else
                        {
                            Console.Clear();
                            Console.WriteLine("You have input an incorrect parameter.");
                            Console.WriteLine("Lecture and Laboratory units must be of type integer and");
                            Console.WriteLine("must have a total range of 12 to 18. Please try again.");
                            Console.Write("Press any key to continue . . .");
                            Console.ReadKey(); Console.Clear();
                        }

                    }
                    while (isInCorrectLecLoad);

                    do //DO WHILE LOOP THAT CHECKS AND HANDLES ERRORS FOR THE LABORATORY UNITS INPUT PART
                    {
                        Console.Clear();
                        callTitle();
                        callLabLecUnitHeader();
                        Console.WriteLine("\t\t   Enter Currently Enrolled Lecture Units: " + unitsLec);
                        Console.Write("\t\t   Enter Currently Enrolled Lecture Units: "); checkLabUnits = Convert.ToString(Console.ReadLine());

                        if (Int32.TryParse(checkLabUnits, out unitsLab))
                        {
                            isInCorrectLabLoad = false;
                        }

                        else
                        {
                            Console.Clear();
                            Console.WriteLine("You have input an incorrect parameter.");
                            Console.WriteLine("Lecture and Laboratory units must be of type integer and");
                            Console.WriteLine("must have a total range of 12 to 18. Please try again.");
                            Console.Write("Press any key to continue . . .");
                            Console.ReadKey(); Console.Clear();
                        }

                    }
                    while (isInCorrectLabLoad);

                    if ((unitsLec + unitsLab) < 12)
                    {
                        Console.Clear();
                        Console.WriteLine("You have made an error.");
                        Console.WriteLine("The total number of units inccured is only " + (unitsLec + unitsLab) + (" unit(s)."));
                        Console.WriteLine(); Console.WriteLine();
                        Console.WriteLine("This means the student is UNDERLOADED.");
                        Console.WriteLine("Please input the correct number of units to fix this problem.");
                        Console.WriteLine(); Console.WriteLine();
                        Console.WriteLine("Please note that the MINIMUM number of units allowed is only 12.");
                        Console.WriteLine(); Console.WriteLine();
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        isInCorrectLabLoad = true;
                        isInCorrectLecLoad = true;
                    }

                    else if ((unitsLec + unitsLab) > 18)
                    {
                        Console.Clear();
                        Console.WriteLine("You have made an error.");
                        Console.WriteLine("The total number of units inccured is " + (unitsLec + unitsLab) + (" units."));
                        Console.WriteLine(); Console.WriteLine();
                        Console.WriteLine("This means the student is OVERLOADED.");
                        Console.WriteLine("Please input the correct number of units to fix this problem.");
                        Console.WriteLine(); Console.WriteLine();
                        Console.WriteLine("Please note that the MAXIMUM number of units allowed is only 18.");
                        Console.WriteLine(); Console.WriteLine();
                        Console.Write("Press any key to continue . . .");
                        Console.ReadKey(); Console.Clear();
                        isInCorrectLabLoad = true;
                        isInCorrectLecLoad = true;
                    }

                    else if (((unitsLec + unitsLab) <= 18) && ((unitsLec + unitsLab) >= 12))
                    {
                        isInCorrectLoad = false;
                    }
                }
                while (isInCorrectLoad);

comments will be very much appreciated! will reply as soon as I get home from school!

This question has already been answered. Start a new discussion instead.