C#中do while循环返回false仍无法退出的问题排查
问题:C#程序中do-while循环无法正常退出,陷入等待状态
开发的C#程序里,外层do-while循环无法正常退出,会停在空白行等待输入,只有输入以Y开头的内容才会继续执行,输入N的时候反而一直卡在等待状态。程序代码如下:
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; } } }
问题成因
问题出在RunAgain方法的内部do-while循环逻辑:
- 当用户输入以
N开头的内容时,代码将done设为false,但循环条件是while (!done),也就是只要done为false,循环就会继续执行,导致程序一直停在等待输入的状态,无法退出该方法。 - 只有当
done被设为true(输入以Y开头的内容)时,内部循环才会退出,方法返回true,外层循环继续执行。
解决办法
修改RunAgain方法,确保无论用户输入Y还是N,内部循环都能退出,同时返回正确的布尔值来控制外层循环:
private bool RunAgain() { bool shouldContinue = false; bool isValidInput = false; Console.WriteLine(); //blankline Console.Write("Run again? (y/n) "); do { string str = Console.ReadLine(); if (string.IsNullOrEmpty(str)) { Console.Write("Please enter y or n: "); continue; } str = str.ToUpper(); if (str[0] == 'Y') { shouldContinue = true; isValidInput = true; } else if (str[0] == 'N') { shouldContinue = false; isValidInput = true; } else { Console.Write("Invalid input, please enter y or n: "); } } while (!isValidInput); return shouldContinue; }
修改说明
- 新增
isValidInput变量,专门用来控制内部循环的退出条件,只要输入了Y/N就标记为有效输入,退出循环。 shouldContinue变量用来存储用户的选择,返回给外层循环决定是否继续执行。- 增加了空输入和无效输入的提示,提升用户体验。
内容的提问来源于stack exchange,提问作者NotSmart
相关产品推荐
相关产品推荐

