Home > Software engineering >  c# do while loop exit even when the return is false
c# do while loop exit even when the return is false

Time:10-21

I have this C# program that, and this loop doesn't want to exit, it just becomes a blank row until the user answers yes? Not sure why or how this is happening. https://dotnetfiddle.net/A6vJtd

using System;
namespace Assignment2
{
    
    
    class FunFeatures
    {
        private string name = "";
        private string email = "";

                static void Main(string[] args)
        {
            Console.Title = "Strings, selection and interation in C#";
            FunFeatures funObj = new FunFeatures();
            funObj.Start();

            ContinueToNextPart(); //call the method below

        }

        private static void ContinueToNextPart()
        {
            Console.WriteLine("\nPress enter to continue to the next part");
            Console.ReadLine();
            Console.Clear();
        }
        
        public void Start()
        {
            Introduce();

            bool done = false;
            do
            {
                //Call method to read a number 1 to 7 and display
                //name of the day (1 = Monday, 7 = Sunday with a comment
                PredictTheDay();

                //Calculate the length of a given text
                CalculateStrengthLength();

                //Run again or exit
                done = RunAgain();
            } while (!done);
            Console.WriteLine("Welcome back, "   name);
        }



        public void CalculateStrengthLength()
        {
            Console.WriteLine("\nLength of text: Write a text with a number of characters and press Enter");
            Console.WriteLine("It will then calculate the number of chars included  in the text");
            Console.WriteLine("Give me a text of any length, or press Enter to exit!");
            string str = Console.ReadLine();
            int strLength = str.Length;
            Console.WriteLine("\n"  str.ToUpper());
            Console.WriteLine("Number of chars = "   strLength);
        }

        private void Introduce()
        {
            Console.WriteLine("\nLet me know about yourself!");
            ReadName();
            Console.Write("Give me your email please: ");
            email = Console.ReadLine();
            Console.WriteLine("\nHere is your full name and your email.");

            //split first name and last name
            var names = name.Split(" ");
            string fName = names[0];
            string lName = names[1];

            Console.WriteLine(lName   ", "   fName   " "   email);
        }

        public void PredictTheDay()
        {
            Console.WriteLine(); // blank row
            Console.WriteLine("\nI am a fortune teller.");
            Console.Write("Select a number between 1 and 7: ");
            string str = Console.ReadLine();
            int day = int.Parse(str);


            switch (day)
            {
                case 1:
                    // Monday
                    Console.WriteLine("Monday: Keep calm my friend! You can fall apart!");
                    break;
                case 2:
                    //Tuesday
                    Console.WriteLine("Tuesday and Wednesday break your heart!");
                    break;
                case 3:
                    //Wednesday
                    Console.WriteLine("Tuesday and Wednesday break your heart!");
                    break;
                case 4:
                    //Thursday
                    Console.WriteLine("Thursday, OMG, still one day to Friday!");
                    break;
                case 5:
                    //Friday
                    Console.WriteLine("It's Friday! You are in love!");
                    break;
                case 6:
                    //Saturday
                    Console.WriteLine("Saturday, do nothing and do plenty of it!");
                    break;
                case 7:
                    //Sunday
                    Console.WriteLine("And Sunday always comes too soon!");
                    break;

                default: // if user gives a number out of range
                    Console.WriteLine("Not in a good mode? This is not a valid date!");
                    break;
            }
        }

        public void ReadName()
        {
            Console.WriteLine("Your first name please: ");
            string firstname = Console.ReadLine();
            Console.Write("Your last name please: ");
            string lastname = Console.ReadLine().ToUpper();
            name = firstname   " "   lastname;
            Console.WriteLine("Nice to meet you "   firstname   "!");
        }

        //Ask user to whether to continue, 
        //return true if the user answers Y, y or any word beginning
        //with these, or N, n or any word beginning with these. 
        //Otherwise, return false.
        private bool RunAgain()
        {
            bool done = false; //true = y, false = n

            Console.WriteLine(); //blankline
            Console.Write("Run again? (y/n) ");

            do
            {
                string str = Console.ReadLine();
                //change str to uppercase letters to make comparison 
                //easier
                str = str.ToUpper();

                if (str[0] == 'Y')   //str[0]is the first letter in the string
                {
                    // continue wit
                    done = true;
                }
                else if (str[0] == 'N')
                {
                    // do not continue with calculation 
                    done = false;
                }
            } while (!done);   //if (!done) is same as: if (done == false)
            return done;
        }
    }
}

CodePudding user response:

You need to distinguish 2 different things here:

  1. The user wants to continue (which you have)
  2. The user made valid input (which you don't have)

You are trying to achieve everything with a single boolean, which will not work.

There are several possibilities to make this work. At your level of understanding, I'd say let's introduce a second boolean:

private bool RunAgain()
{
    Console.WriteLine();
    Console.Write("Run again? (y/n) ");

    bool done = false; //true = y, false = n
    bool validinput = false; // no input is invalid input
    do
    {
        string str = Console.ReadLine();
        str = str.ToUpper();

        if (str[0] == 'Y')
        {
            done = true;
            validinput  = true;
        }
        else if (str[0] == 'N')
        {
            done = false;
            validinput  = true;
        }
    } while (!validinput);  
    return done;
}

Note that you have inverse logic here: the method is called RunAgain(), and the variable name is called done, where my understanding of done is that I don't want to continue.

Let's fix that and make shorter code like

private bool RunAgain()
{
    Console.WriteLine();
    Console.Write("Run again? (y/n) ");

    while(true) // yes, it's endless ...
    {
        string str = Console.ReadLine();
        str = str.ToUpper();

        if (str[0] == 'Y')
        {
            return       // ... except if you jump out 
                  false; // False = not run again 
        }
        else if (str[0] == 'N')
        {
            return       // ... except if you jump out 
                  true;  // True = run again 
        }
    }
}

CodePudding user response:

This loop here:

 do
            {
                string str = Console.ReadLine();
                //change str to uppercase letters to make comparison 
                //easier
                str = str.ToUpper();

                if (str[0] == 'Y')   //str[0]is the first letter in the string
                {
                    // continue wit
                    done = true;
                }
                else if (str[0] == 'N')
                {
                    // do not continue with calculation 
                    done = false;
                }
            } while (!done);   //if (!done) is same as: if (done == false)

doesn't have a leaving mechanism when you input no. You are checking if they entered yes or no and if they entered no you are just looping over and over again, since while(!false) means while(true) which means once they enter no you are commanding to loop again. You can do something like:

            do
            {
                string str = Console.ReadLine();
                //change str to uppercase letters to make comparison 
                //easier
                str = str.ToUpper();

                if (str[0] == 'Y')   //str[0]is the first letter in the string
                {
                    // continue wit
                    done = true;
                }
                else if (str[0] == 'N')
                {
                    // do not continue with calculation 
                    done = false;
                    break;
                }
            } while (!done);   //if (!done) is same as: if (done == false)
            return done;

This part is also wrong

do
            {
                //Call method to read a number 1 to 7 and display
                //name of the day (1 = Monday, 7 = Sunday with a comment
                PredictTheDay();

                //Calculate the length of a given text
                CalculateStrengthLength();

                //Run again or exit
                done = RunAgain();
            } while (!done);

You are receiving a false from RunAgain() when the user answers no which means you should stop the loop but since you again have while(!done) you are resolving !false to true. It should be

do
            {
                //Call method to read a number 1 to 7 and display
                //name of the day (1 = Monday, 7 = Sunday with a comment
                PredictTheDay();

                //Calculate the length of a given text
                CalculateStrengthLength();

                //Run again or exit
                done = RunAgain();
            } while (done);
  •  Tags:  
  • c#
  • Related