VB.NET Substring函数工作异常及ArgumentOutOfRangeException报错求助
问题原因分析
- Substring方法参数理解错误:
Substring(startIndex, length)的第二个参数是截取的长度,不是结束位置的索引。你直接把IndexOf("m")作为第二个参数,导致截取长度远大于实际需要,所以theLine2会读到多余内容;到theLine3时,计算出的长度超出字符串范围,直接触发ArgumentOutOfRangeException。 - 循环边界错误:
File.ReadAllLines("this.txt").Length是文件总行数,比如有5行,索引范围是0-4,但你的循环写的是For t = 0 To lineCount,会多循环一次,最后一次sw2.ReadLine()会返回Nothing,对空字符串调用Substring必然报错。 - 重复读取文件:先用
File.ReadAllLines读一次文件拿行数,再用StreamReader读第二次,既浪费资源,还可能因流位置问题导致读取异常。 - 未处理格式异常:如果某行缺少分隔符(比如没有"a"或"b"),
IndexOf会返回-1,后续Substring操作也会报错。
解决办法
方案1:修正原代码的参数与循环问题
Imports System.IO Public Class Form1 Dim array2(200) As String Dim theLine1 As String Dim theLine2 As String Dim theLine3 As String Dim theLine4 As String Private Sub btn_Read_Click(sender As Object, e As EventArgs) Handles btn_Read.Click ' 一次性读取所有行,避免重复IO操作 Dim allLines = File.ReadAllLines("this.txt") ' 循环边界改为0到总行数-1,避免多循环一次 For t = 0 To allLines.Length - 1 Dim currentLine = allLines(t).Trim() ' 跳过空行 If String.IsNullOrEmpty(currentLine) Then Continue For ' 预先获取所有分隔符的索引,避免重复计算 Dim idxN = currentLine.IndexOf("n") Dim idxM = currentLine.IndexOf("m") Dim idxA = currentLine.IndexOf("a") Dim idxB = currentLine.IndexOf("b") ' 检查所有分隔符是否存在,避免索引为-1的情况 If idxN = -1 Or idxM = -1 Or idxA = -1 Or idxB = -1 Then ' 可在此添加错误提示,比如跳过该行或弹窗提醒 Continue For End If ' 正确计算Substring的长度:结束索引 - 起始索引 theLine1 = currentLine.Substring(0, idxN).Trim() theLine2 = currentLine.Substring(idxN + 1, idxM - (idxN + 1)).Trim() theLine3 = currentLine.Substring(idxM + 1, idxA - (idxM + 1)).Trim() theLine4 = currentLine.Substring(idxA + 1, idxB - (idxA + 1)).Trim() array2(t) = currentLine Next End Sub End Class
方案2:用Split方法简化提取(更推荐)
既然每行格式固定为值1 n 值2 m 值3 a 值4 b,可以直接按空格分割后取对应位置的元素,代码更简洁可靠:
Imports System.IO Public Class Form1 Dim array2(200) As String Dim theLine1 As String Dim theLine2 As String Dim theLine3 As String Dim theLine4 As String Private Sub btn_Read_Click(sender As Object, e As EventArgs) Handles btn_Read.Click Dim allLines = File.ReadAllLines("this.txt") For t = 0 To allLines.Length - 1 Dim currentLine = allLines(t).Trim() If String.IsNullOrEmpty(currentLine) Then Continue For ' 按空格分割,自动移除空元素 Dim parts = currentLine.Split({" "}, StringSplitOptions.RemoveEmptyEntries) ' 检查分割后的元素数量是否符合预期(应为8个:值1,n,值2,m,值3,a,值4,b) If parts.Length <> 8 Then Continue For End If ' 直接取对应位置的元素 theLine1 = parts(0) theLine2 = parts(2) theLine3 = parts(4) theLine4 = parts(6) array2(t) = currentLine Next End Sub End Class
方案3:正则表达式提取(适配复杂格式)
如果分隔符前后的空格不固定,或格式有轻微变化,用正则匹配更灵活:
Imports System.IO Imports System.Text.RegularExpressions Public Class Form1 Dim array2(200) As String Dim theLine1 As String Dim theLine2 As String Dim theLine3 As String Dim theLine4 As String ' 预编译正则表达式,提升重复匹配的性能 Private Shared ReadOnly linePattern As New Regex("^\s*(\S+)\s+n\s+(\S+)\s+m\s+(\S+)\s+a\s+(\S+)\s+b\s*$", RegexOptions.Compiled) Private Sub btn_Read_Click(sender As Object, e As EventArgs) Handles btn_Read.Click Dim allLines = File.ReadAllLines("this.txt") For t = 0 To allLines.Length - 1 Dim currentLine = allLines(t) Dim match = linePattern.Match(currentLine) If match.Success Then theLine1 = match.Groups(1).Value theLine2 = match.Groups(2).Value theLine3 = match.Groups(3).Value theLine4 = match.Groups(4).Value array2(t) = currentLine End If Next End Sub End Class
内容的提问来源于stack exchange,提问作者user22672706
相关产品推荐
相关产品推荐

