You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF计算器多运算符连续使用异常问题求助

WPF计算器多运算符处理问题

我的WPF计算器还没做完,核心卡在运算符处理上:所有运算符共用同一个处理逻辑,只能支持单次运算,第二次按运算符会直接覆盖前一个;哪怕输入包含两个及以上运算符的表达式,最终计算也只会用最后一个运算符。

忽略x²和sqrt(这两个运算符,下面是相关代码:

public partial class MainWindow : Window
{
    string Input = " ";
    string Operator = null;
    public MainWindow()
    {
        InitializeComponent();
        this.SizeToContent = SizeToContent.Width;
        this.SizeToContent = SizeToContent.Height;
    }

    private void Number_Click(object sender, RoutedEventArgs e)
    {
        string Input = " ";

        Button button = (Button)sender;
        Input += button.Content.ToString();
        Equation.Text += button.Content.ToString();
    }

    private void Operator_Click(object sender, RoutedEventArgs e)
    {
        Button button = (Button)sender;

        if (!string.IsNullOrEmpty(Operator))
        {
            Operator += button.Content.ToString();
            Input = " ";
        }

        Operator = button.Content.ToString();
        Equation.Text += button.Content.ToString();
    }

    private void b_equal_Click(object sender, RoutedEventArgs e)
    {
        Equation.Text = Calculon(Operator);
    }
    private string Calculon(string Operator)
    {
        double Result = 0;
        string Error = "Syntaxfehler";
        string[] Text = Equation.Text.Split(" ");

        for (int i = 0; i < Text.Length - 2;)
        {
            double numberOne = Convert.ToDouble(Text[i]);
            double numberTwo = Convert.ToDouble(Text[i + 2]);

            if (Operator == " x ")
            {
                Result = numberOne * numberTwo;
            }

            if (Operator == " - ")
            {
                Result = numberOne - numberTwo;
            }

            if (Operator == " + ")
            {
                Result = numberOne + numberTwo;
            }

            if (Operator == " / ")
            {
                Result = numberOne / numberTwo;
            }

            if (Operator == " ² ")
            {
                Result = Math.Round(numberOne,2);
            }

            if (Operator == " sqrt( ")
            {
                Result = Math.Sqrt(numberOne);
            }
           
            i += 2;

            Text[i] = Result.ToString();

        }
        if (Result.Equals(double.NaN))
        {
           return Error;
        }
        return Result.ToString();
    }
    private void b_Clear_Click(object sender, RoutedEventArgs e)
    {
        Equation.Text = null;
    }

    private void bpunkt_Click(object sender, RoutedEventArgs e)
    {
        Equation.Text += ",";
    }
}

我试过定义两个Operator变量,但只在两个运算符的场景下有效,超过两个就又出现问题;也想过用循环处理,但因为按下运算符时输入的表达式还没完成,不知道该怎么实现,求帮忙解决。


问题分析

你的代码存在几个核心问题:

  1. 变量作用域错误:Number_Click里重新定义了局部Input,导致全局Input完全没用,输入的数字没被正确记录
  2. 运算符存储逻辑矛盾:全局Operator是单个字符串,每次点击都会直接覆盖前值;且Operator_Click里先拼接再覆盖的逻辑完全无效,没法存储多运算符
  3. 计算逻辑偏差:Calculon只接收最后一个运算符,用它处理所有运算步骤,完全忽略表达式里的实际运算符顺序

修复方案

改用列表存储数字和运算符的方式,把每一步的操作都记录下来,支持多运算符连续计算。

修改后的完整代码

public partial class MainWindow : Window
{
    // 存储输入的数字与对应运算符
    private List<double> _numbers = new List<double>();
    private List<string> _operators = new List<string>();
    private string _currentInput = "";

    public MainWindow()
    {
        InitializeComponent();
        SizeToContent = SizeToContent.WidthAndHeight;
    }

    private void Number_Click(object sender, RoutedEventArgs e)
    {
        Button button = (Button)sender;
        _currentInput += button.Content.ToString();
        Equation.Text += button.Content.ToString();
    }

    private void Operator_Click(object sender, RoutedEventArgs e)
    {
        Button button = (Button)sender;
        string op = button.Content.ToString();

        // 先存储当前输入的数字
        if (!string.IsNullOrEmpty(_currentInput))
        {
            if (double.TryParse(_currentInput, out double num))
            {
                _numbers.Add(num);
                _currentInput = "";
            }
            else
            {
                Equation.Text = "输入错误";
                ClearAll();
                return;
            }
        }

        // 存储当前运算符
        _operators.Add(op);
        Equation.Text += op;
    }

    private void b_equal_Click(object sender, RoutedEventArgs e)
    {
        // 存储最后一个输入的数字
        if (!string.IsNullOrEmpty(_currentInput))
        {
            if (double.TryParse(_currentInput, out double num))
            {
                _numbers.Add(num);
                _currentInput = "";
            }
            else
            {
                Equation.Text = "输入错误";
                ClearAll();
                return;
            }
        }

        // 检查数字与运算符数量是否匹配
        if (_numbers.Count != _operators.Count + 1)
        {
            Equation.Text = "语法错误";
            ClearAll();
            return;
        }

        // 按顺序执行计算
        double result = _numbers[0];
        for (int i = 0; i < _operators.Count; i++)
        {
            string op = _operators[i];
            double nextNum = _numbers[i + 1];

            switch (op)
            {
                case " + ":
                    result += nextNum;
                    break;
                case " - ":
                    result -= nextNum;
                    break;
                case " x ":
                    result *= nextNum;
                    break;
                case " / ":
                    if (nextNum == 0)
                    {
                        Equation.Text = "除以零错误";
                        ClearAll();
                        return;
                    }
                    result /= nextNum;
                    break;
                // 忽略x²和sqrt(,暂不处理
            }
        }

        Equation.Text = result.ToString();
        // 将结果作为下一次计算的初始值
        ClearAll();
        _currentInput = result.ToString();
    }

    private void b_Clear_Click(object sender, RoutedEventArgs e)
    {
        ClearAll();
        Equation.Text = "";
    }

    private void bpunkt_Click(object sender, RoutedEventArgs e)
    {
        // 避免重复输入小数点
        if (!_currentInput.Contains(","))
        {
            _currentInput += ",";
            Equation.Text += ",";
        }
    }

    // 清空所有存储数据
    private void ClearAll()
    {
        _numbers.Clear();
        _operators.Clear();
        _currentInput = "";
    }
}

关键修改说明

  1. 存储结构优化:用_numbers和_operators列表分别记录输入的数字与运算符,完美支持多步骤运算
  2. 输入逻辑修复:移除局部变量覆盖问题,增加小数点重复输入判断,提升输入合法性
  3. 运算符处理修正:每次点击运算符时先存储当前输入的数字,再记录运算符,确保每一步操作都被保存
  4. 计算逻辑重构:按输入顺序遍历运算符列表,依次处理相邻数字;增加错误判断(语法错误、除以零)
  5. 交互体验优化:计算完成后将结果作为下一次计算的初始值,符合普通计算器使用习惯

内容的提问来源于stack exchange,提问作者Laszlo Adams

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:51:14