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:
- The user wants to continue (which you have)
- 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);