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

Visual Basic进制转换程序栈溢出问题求助

进制转换应用栈溢出问题解决

我正在开发一款进制转换应用,功能是用户输入某一种进制的数值后,其余三个文本框自动显示对应的其他进制数值。但在为oct2_textbox添加代码时,程序出现了栈溢出错误,希望解决该问题的同时维持系统的动态响应式自动转换功能。

Visual Basic中制作的界面

原始代码

Imports System.ComponentModel
Imports System.Windows.Forms.VisualStyles.VisualStyleElement

Public Class Form1
    Private Sub Label3_Click(sender As Object, e As EventArgs)

    End Sub

    Private Sub TextBox5_TextChanged(sender As Object, e As EventArgs)

    End Sub



    Private Sub oct_KeyPress(sender As Object, e As KeyPressEventArgs)

        If Not (e.KeyChar >= "0"c AndAlso e.KeyChar <= "7"c OrElse Char.IsControl(e.KeyChar)) Then
            e.Handled = True
        End If
    End Sub

    Private Sub HEX_TextChanged(sender As Object, e As EventArgs) Handles HEX.TextChanged

        Dim HEX_num As Integer
        If Integer.TryParse(HEX.Text, System.Globalization.NumberStyles.HexNumber, Nothing, HEX_num) Then

            oct2.Text = Convert.ToString(HEX_num, 8)
            DECDEC.Text = Convert.ToString(HEX_num, 10)

            bin.Text = Convert.ToString(HEX_num, 2)

        End If
        bin.Text = bin.Text.ToString()

    End Sub
    Private Sub HEX_KeyPress(sender As Object, e As KeyPressEventArgs) Handles HEX.KeyPress
        ' 临时移除事件处理程序
        RemoveHandler HEX.KeyPress, AddressOf HEX_KeyPress

        Dim inputChar As Char = Char.ToUpper(e.KeyChar)

        If Not (Char.IsDigit(inputChar) OrElse
            (inputChar >= "A"c AndAlso inputChar <= "F"c) OrElse
            Char.IsControl(e.KeyChar)) Then
            e.Handled = True
        End If

        ' 重新附加事件处理程序
        AddHandler HEX.KeyPress, AddressOf HEX_KeyPress
    End Sub


    Private Sub DECDEC_TextChanged(sender As Object, e As EventArgs) Handles DECDEC.TextChanged
        Dim decdec_num As Integer
        If Integer.TryParse(DECDEC.Text, decdec_num) Then
            oct2.Text = Convert.ToString(decdec_num, 8)
            HEX.Text = Convert.ToString(decdec_num, 16)
            bin.Text = Convert.ToString(decdec_num, 2)
        End If
    End Sub


    Private Sub DECDEC_KeyPress(sender As Object, e As KeyPressEventArgs) Handles DECDEC.KeyPress

        If Not (Char.IsDigit(e.KeyChar) OrElse Char.IsControl(e.KeyChar)) Then
            e.Handled = True
        End If
    End Sub

    Private Sub bin_TextChanged(sender As Object, e As EventArgs) Handles bin.TextChanged
        ' 临时移除事件处理程序
        RemoveHandler bin.TextChanged, AddressOf bin_TextChanged

        Dim bin_str As String = bin.Text.Trim()
        If Not String.IsNullOrEmpty(bin_str) AndAlso bin_str.All(Function(c) c = "0" OrElse c = "1") Then
            Dim bin_num As Integer = Convert.ToInt32(bin_str, 2)
            DECDEC.Text = bin_num.ToString()
            HEX.Text = Convert.ToString(bin_num, 16)
            oct2.Text = Convert.ToString(bin_num, 8)
        End If

        ' 重新附加事件处理程序
        AddHandler bin.TextChanged, AddressOf bin_TextChanged
    End Sub


    Private Sub bin_KeyPress(sender As Object, e As KeyPressEventArgs) Handles bin.KeyPress
        ' 临时移除事件处理程序
        RemoveHandler bin.KeyPress, AddressOf bin_KeyPress

        If Not (e.KeyChar = "0"c OrElse e.KeyChar = "1"c OrElse Char.IsControl(e.KeyChar)) Then
            e.Handled = True
        End If

        ' 重新附加事件处理程序
        AddHandler bin.KeyPress, AddressOf bin_KeyPress
    End Sub


    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        oct2.Text = ""
        HEX.Text = ""
        DECDEC.Text = ""
        bin.Text = ""


    End Sub

    Private Sub GroupBox4_Enter(sender As Object, e As EventArgs) Handles GroupBox4.Enter

    End Sub

    Private Sub oct2_TextChanged(sender As Object, e As EventArgs) Handles oct2.TextChanged
        ' 临时移除事件处理程序
        RemoveHandler oct2.TextChanged, AddressOf oct2_TextChanged

        Dim oct2_num As Integer
        If Integer.TryParse(oct2.Text, oct2_num) Then
            DECDEC.Text = Convert.ToString(oct2_num, 10)
            HEX.Text = Convert.ToString(oct2_num, 16)
            bin.Text = Convert.ToString(oct2_num, 2)
        End If

        ' 重新附加事件处理程序
        AddHandler oct2.TextChanged, AddressOf oct2_TextChanged
    End Sub


End Class

问题原因

  1. 事件循环触发:修改oct2.Text会触发oct2_TextChanged事件,该事件又会修改DECDEC.Text,进而触发DECDEC_TextChanged事件,而后者又会修改oct2.Text,形成无限循环,导致调用栈不断累积最终溢出。
  2. 八进制解析错误:Integer.TryParse(oct2.Text, oct2_num)默认按十进制解析八进制字符串,导致转换结果错误,同时加剧循环问题。

解决代码及说明

Imports System.ComponentModel
Imports System.Globalization
Imports System.Windows.Forms.VisualStyles.VisualStyleElement

Public Class Form1
    ' 标记是否正在更新文本框,阻止事件循环触发
    Private isUpdating As Boolean = False

    Private Sub Label3_Click(sender As Object, e As EventArgs)

    End Sub

    Private Sub TextBox5_TextChanged(sender As Object, e As EventArgs)

    End Sub

    Private Sub oct_KeyPress(sender As Object, e As KeyPressEventArgs)
        If Not (e.KeyChar >= "0"c AndAlso e.KeyChar <= "7"c OrElse Char.IsControl(e.KeyChar)) Then
            e.Handled = True
        End If
    End Sub

    Private Sub HEX_TextChanged(sender As Object, e As EventArgs) Handles HEX.TextChanged
        If isUpdating Then Return
        isUpdating = True

        Dim hexNum As Integer
        If Integer.TryParse(HEX.Text, NumberStyles.HexNumber, Nothing, hexNum) Then
            oct2.Text = Convert.ToString(hexNum, 8)
            DECDEC.Text = hexNum.ToString()
            bin.Text = Convert.ToString(hexNum, 2)
        Else
            ' 输入无效时清空其他框
            oct2.Text = ""
            DECDEC.Text = ""
            bin.Text = ""
        End If

        isUpdating = False
    End Sub

    Private Sub HEX_KeyPress(sender As Object, e As KeyPressEventArgs) Handles HEX.KeyPress
        Dim inputChar As Char = Char.ToUpper(e.KeyChar)
        If Not (Char.IsDigit(inputChar) OrElse (inputChar >= "A"c AndAlso inputChar <= "F"c) OrElse Char.IsControl(e.KeyChar)) Then
            e.Handled = True
        End If
    End Sub

    Private Sub DECDEC_TextChanged(sender As Object, e As EventArgs) Handles DECDEC.TextChanged
        If isUpdating Then Return
        isUpdating = True

        Dim decNum As Integer
        If Integer.TryParse(DECDEC.Text, decNum) Then
            oct2.Text = Convert.ToString(decNum, 8)
            HEX.Text = Convert.ToString(decNum, 16).ToUpper()
            bin.Text = Convert.ToString(decNum, 2)
        Else
            oct2.Text = ""
            HEX.Text = ""
            bin.Text = ""
        End If

        isUpdating = False
    End Sub

    Private Sub DECDEC_KeyPress(sender As Object, e As KeyPressEventArgs) Handles DECDEC.KeyPress
        If Not (Char.IsDigit(e.KeyChar) OrElse Char.IsControl(e.KeyChar)) Then
            e.Handled = True
        End If
    End Sub

    Private Sub bin_TextChanged(sender As Object, e As EventArgs) Handles bin.TextChanged
        If isUpdating Then Return
        isUpdating = True

        Dim binStr As String = bin.Text.Trim()
        If Not String.IsNullOrEmpty(binStr) AndAlso binStr.All(Function(c) c = "0"c OrElse c = "1"c) Then
            Dim binNum As Integer = Convert.ToInt32(binStr, 2)
            DECDEC.Text = binNum.ToString()
            HEX.Text = Convert.ToString(binNum, 16).ToUpper()
            oct2.Text = Convert.ToString(binNum, 8)
        Else
            DECDEC.Text = ""
            HEX.Text = ""
            oct2.Text = ""
        End If

        isUpdating = False
    End Sub

    Private Sub bin_KeyPress(sender As Object, e As KeyPressEventArgs) Handles bin.KeyPress
        If Not (e.KeyChar = "0"c OrElse e.KeyChar = "1"c OrElse Char.IsControl(e.KeyChar)) Then
            e.Handled = True
        End If
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        isUpdating = True
        oct2.Text = ""
        HEX.Text = ""
        DECDEC.Text = ""
        bin.Text = ""
        isUpdating = False
    End Sub

    Private Sub GroupBox4_Enter(sender As Object, e As EventArgs) Handles GroupBox4.Enter

    End Sub

    Private Sub oct2_TextChanged(sender As Object, e As EventArgs) Handles oct2.TextChanged
        If isUpdating Then Return
        isUpdating = True

        Dim octNum As Integer
        ' 正确解析八进制字符串
        If Integer.TryParse(oct2.Text, NumberStyles.Octal, Nothing, octNum) Then
            DECDEC.Text = octNum.ToString()
            HEX.Text = Convert.ToString(octNum, 16).ToUpper()
            bin.Text = Convert.ToString(octNum, 2)
        Else
            DECDEC.Text = ""
            HEX.Text = ""
            bin.Text = ""
        End If

        isUpdating = False
    End Sub
End Class

优化点说明

  • 新增isUpdating布尔变量,所有TextChanged事件开头判断该变量,阻止循环触发
  • 修复八进制解析逻辑,使用NumberStyles.Octal正确解析八进制字符串
  • 移除不必要的事件移除/重新附加逻辑,简化代码结构
  • 十六进制结果转为大写,符合常规使用习惯
  • 输入无效时自动清空其他文本框,避免显示错误内容

内容的提问来源于stack exchange,提问作者Pacjoseph Novabos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:05:53