【问题标题】:Endless loop on nested while statement嵌套while语句上的无限循环
【发布时间】:2020-02-07 13:46:03
【问题描述】:

我正在尝试将 2 个 while 循环用于 C# 控制台程序。外部是重复程序菜单和功能,直到用户退出。我用作验证用户输入的内部循环(需要将其解析为 int)。

内部循环似乎工作正常,但是一旦程序到达 switch 语句,它似乎会无休止地循环 switch 条件。因此,一旦我相信外部 while 循环使其无休止地写入,而不是写入控制台。只有将标志设置为假的情况才会按预期停止。

有人可以解释发生了什么吗?我将如何更新标志以使外部 while 循环不会无休止地执行开关中的功能?程序应返回用户菜单并在所有情况下等待输入,除非用户选择 7 结束程序。我已经盯着这个看了好几个小时了。请指教!

using System;
using static System.Console;
using System.Collections.Generic;

namespace Project02AreaCalculator
{
  class Program
  {
    static private bool flag = true;
    static void Main(string[] args)
    {

        string inputvalue = "";
        int caseSwitch;

        // repeat program until flag is set to false by user selecting 7 to exit
        do
        {
            // repeat menu until user input can be parsed into an integer
            while (!int.TryParse(inputvalue, out caseSwitch))
            {
                flag = false;
                Console.WriteLine("Shape Area Calculator");
                Console.WriteLine("******************************************");
                Console.WriteLine("\t1. Circle");
                Console.WriteLine("\t2. Square");
                Console.WriteLine("\t3. Rectangle");
                Console.WriteLine("\t4. Rhombus");
                Console.WriteLine("\t5. Parallelogram");
                Console.WriteLine("\t6. Trapezoid");
                Console.WriteLine("\t7. Exit");
                Console.WriteLine("******************************************");
                Console.WriteLine("Select a shape type to calculate");
                inputvalue = ReadLine();
            }

            //convert input to integer and assign to caseSwitch
            caseSwitch = Convert.ToInt32(inputvalue);

            switch (caseSwitch)
            {
                case 1:
                    CalculateCircle();
                    //Clear();
                    flag = true;
                    break;
                case 2:
                    CalculateSquare();
                    // Clear();
                    flag = true;
                    break;
                case 3:
                    CalculateRectangle();
                    //Clear();
                    flag = true;
                    break;
                case 4:
                    CalculateRhombus();
                    //Clear();
                    flag = true;
                    break;
                case 5:
                    CalculateParallelogram();
                    //Clear();
                    flag = true;
                    break;
                case 6:
                    CalculateTrapezoid();
                    //Clear();
                    flag = true;
                    break;
                case 7:
                    //Clear();
                    Console.WriteLine("Goodbye! Press any key to end");
                    ReadKey();
                    flag = false;
                    break;
                default:
                    // Clear();
                    Console.WriteLine("Invalid Selection, Select 1-7");
                    flag = true;
                    break;
            }


        } while (caseSwitch != 7);

    }//end main

        //****************METHODS SECTION ****************************************************************************
        static private void CalculateCircle()
        {
            //area = pi * radius * radius (or pi times radius squared)
            Console.Clear();
            Console.WriteLine("Circle Area Calculator");
            Console.WriteLine("Enter the length of the circle's radius (-1 to exit back to menu):");
            Console.ReadKey();

        }
        static private void CalculateSquare()
        {
            //area = side * side (or side squared)
            Console.Clear();
            Console.WriteLine("Square Area Calculator");
            Console.WriteLine("Enter the length of one side of the square (-1 to exit back to menu):");
            Console.ReadKey();
          }
        static private void CalculateRectangle()
        {
            //area = Length * Width
            Console.Clear();
            Console.WriteLine("Rectangle Area Calculator");
            Console.WriteLine("Enter the length of one side of the Rectangle (-1 to exit back to menu):");
            Console.WriteLine("Enter the length of an opposing side of the Rectangle (-1 to exit back to menu):");
            Console.ReadKey();
        }

        static private void CalculateRhombus()
        {
            //area = ½ a * b (a and b being diagonals)
            Console.Clear();
            Console.WriteLine("Rhombus Area Calculator");
            Console.WriteLine("Enter the length of one diagonal of the rhombus (-1 to exit back to menu):");
            Console.WriteLine("Enter the length of the other diagonal of the rhombus (-1 to exit back to menu):");
            Console.ReadKey();
         }
        static private void CalculateParallelogram()
        {
            //area = base * height
            Console.WriteLine("Parallelogram Area Calculator");
            Console.WriteLine("Enter the length of the base of the Parallelogram (-1 to exit back to menu):");
            Console.WriteLine("Enter the height of the Parallogram (-1 to exit back to menu):");
            Console.ReadKey();
         }

        static private void CalculateTrapezoid()
        {
            //area = ½ height * (largeBase + smallBase)
            Console.WriteLine("Trapezoid Area Calculator"); 
            Console.ReadKey();
         }
    }
}

【问题讨论】:

标签: c# while-loop


【解决方案1】:

只是为了让您的程序运行,请执行以下更改,

在检查用户输入之前重置 inputvalue 和 caseSwitch 的值,如下所示,

...
...
do
            {
                inputvalue = "";
                caseSwitch = 0;
                // repeat menu until user input can be parsed into an integer
                while (!int.TryParse(inputvalue, out caseSwitch))
                {
...
...

而且,下面的语句也不是必需的

caseSwitch = Convert.ToInt32(inputvalue);

其他问题是,

在所有函数中,它都要求用户输入,但输入没有被使用或存储在任何变量中。

即使在CalculateParallelogram、CalculateRhombus 等某些函数中,用户也被要求输入两个值length 和height,并且只接受一个输入,而且该输入也是单个键(Console.ReadKey())。

所以将 ReadKey 更改为 ReadLine 并在被询问的地方接受两个输入。 此代码中还有其他逻辑问题需要改进。

【讨论】:

  • 我实际上只需要在外部 do 循环中移动“inputValue”声明,以便在每次迭代时重置它。 caseSwitch 声明必须保留在 do-while 循环之外(否则它超出了 while 条件的范围。谢谢 Mohit!感谢您的帮助!
【解决方案2】:

尝试添加

inputvalue="";

之后

caseSwitch = Convert.ToInt32(inputvalue);

【讨论】:

  • 他为什么要这么做?
  • 因为他没有这样做?你为什么要问这个?你看代码了吗?
  • @uwekeim 因为否则菜单将不再显示。另一种选择是将 while 移动到块的末尾(将其变为 do ... while 循环)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 2021-05-12
  • 2013-05-17
  • 1970-01-01
  • 2016-10-30
  • 2023-03-30
  • 1970-01-01
相关资源
最近更新 更多