Arrays 如何修复';索引超出了数组的界限';

Arrays 如何修复';索引超出了数组的界限';,arrays,vb.net,Arrays,Vb.net,使用visualbasic。尝试将一系列报告加载到listview时,listview每次加载时都由3列(位置、日期和严重性级别)组成,因为“索引超出了数组的界限”。特别是在我的代码中DOI=reportdetails(1)附近。它正在加载一个文本文件。我有文本文件中的数据,所以我不确定它为什么说我在询问不存在的信息。该程序还对文本文件进行加密 Dim locate, DOI, SeverityLevel, ReportTitles, EReportTitles, ReportDetails(2

使用visualbasic。尝试将一系列报告加载到listview时,listview每次加载时都由3列(位置、日期和严重性级别)组成,因为“索引超出了数组的界限”。特别是在我的代码中DOI=reportdetails(1)附近。它正在加载一个文本文件。我有文本文件中的数据,所以我不确定它为什么说我在询问不存在的信息。该程序还对文本文件进行加密

Dim locate, DOI, SeverityLevel, ReportTitles, EReportTitles, ReportDetails(2) As String

Dim Index As Integer 'Define Variables
Dim FileNum As Integer = FreeFile()
Dim IncidentReport As ListViewItem

lstReports.Items.Clear()

If Dir("ReportTitles.txt") <> "" Then 'If the directory of the file exits then continue

    FileOpen(FileNum, "ReportTitles.txt", OpenMode.Input) 'open file
    Do Until EOF(FileNum)   'Repeat until the end of the file is reached

        EReportTitles = "" 'Clear variables, to safeguard against crashes or errors

        ReportTitles = ""
        EReportTitles = LineInput(FileNum) 'EReportTitles is equal to the current file line

        Dim FileName As String = "ReportTitles.txt"   'Define variables

        Dim I, C As Integer
        Dim Last As Integer = EReportTitles.Length - 1
        Dim ThisChar As Char
        For I = 0 To Last   'Begin for loop 
            ThisChar = EReportTitles.Chars(I)  'Decryption of file
            C = Asc(ThisChar) Xor 22
            ThisChar = Chr(C)
            ReportTitles += ThisChar
        Next
        If ReportTitles <> "" Then
            ReportDetails = Split(ReportTitles, ",")  'Split the lines when a "," is encountered

            locate = ReportDetails(0) 'Assosciate to relevant value in array

            DOI = ReportDetails(1)
            SeverityLevel = ReportDetails(2)

            IncidentReport = New ListViewItem
            IncidentReport.Text = locate    'Add relevant values to IncidentReport ListViewItem variable
            IncidentReport.SubItems.Add(DOI)
            IncidentReport.SubItems.Add(SeverityLevel)

            lstReports.Items.Add(IncidentReport)  'Transfer IncidentReport to listview
        Else

        End If
    Loop
    FileClose(FileNum)  'close file
End If
Dim locate、DOI、SeverityLevel、ReportTitles、EReportTitles、ReportDetails(2)作为字符串
将索引设置为整数“定义变量”
Dim FileNum作为整数=FreeFile()
Dim Incident报告为ListViewItem
lstrepts.Items.Clear()
如果Dir(“ReportTitles.txt”)“Then”如果文件的目录退出,则继续
FileOpen(FileNum,“ReportTitles.txt”,OpenMode.Input)打开文件
执行直到EOF(FileNum)'重复,直到到达文件末尾
EReportTitles=“”清除变量,以防止崩溃或错误
ReportTitles=“”
EReportTitles=LineInput(FileNum)'EReportTitles等于当前文件行
Dim文件名为String=“ReportTitles.txt”'定义变量
作为整数的Dim I,C
Dim Last As Integer=EReportTitles.Length-1
将此字符变暗为字符
对于I=0到最后一个“开始循环”
ThisChar=EReportTitles.Chars(I)'文件解密
C=Asc(ThisChar)异或22
ThisChar=Chr(C)
ReportTitles+=ThisChar
下一个
如果报告标题为“”,则
ReportDetails=Split(ReportTitles,“,”)遇到“,”时拆分行
locate=ReportDetails(0)与数组中的相关值关联
DOI=报告详细信息(1)
SeverityLevel=报告详细信息(2)
IncidentReport=新的ListViewItem
IncidentReport.Text=locate'向IncidentReport ListViewItem变量添加相关值
意外事故报告.子项.添加(DOI)
意外事故报告.子项.添加(严重级别)
lstrepts.Items.Add(IncidentReport)'将IncidentReport传输到listview
其他的
如果结束
环
FileClose(FileNum)'关闭文件
如果结束
预期结果是将所有报告位置、日期和严重性级别加载到listview中


对于此问题的格式设置,我也很抱歉,我不熟悉堆栈溢出。

没有必要像这样声明
ReportDetails

ReportDetails(2) As String
因为这样会创建一个从未使用过的数组。在这里:

ReportDetails = Split(ReportTitles, ",")
您仍在创建一个新数组,该数组的长度将由
ReportTitles
中的分隔符数决定。如果您被告知1是该数组的无效索引,那么该数组只能包含1个元素,这意味着
ReportTitles
不包含任何分隔符

这不是我们应该向您解释的事情,因为您可以通过调试轻松地看到它,并且您应该在发布之前始终进行调试。在代码顶部设置一个断点,逐行遍历,并检查每一步的状态。您可以轻松查看
ReportTitles
ReportDetails
的内容以及其他任何内容,以了解它们是否符合您的期望


如果这里的重点是读取CSV文件,那么您确实应该使用
TextFieldParser
类。该类的文档包括一个代码示例。

这需要.Net标准2.1,因此我不确定VB.Net是否可以为
String.Create()
方法使用所需的
SpanAction
,但如果支持该方法,它的性能将大大优于原始方法

lstReports.Items.Clear()

'Read and "Decrypt" (and I use that term loosely) the file with only a single heap allocation
Dim file As String
Using fs As FileStream = File.OpenRead("ReportTitles.txt")
    file = String.Create(fs.Length, fs, 
        Sub(chars, stream)
            For i As Integer = 0 To stream.Length - 1
                'THIS IS NOT ENCRYPTION! At best, it's obfuscation.
                chars(i) = Chr(fs.ReadByte() Xor 22)
            Next
        End Sub)
End Using

'Use an actual CSV parser
Using reader As New StringReader(file), _
      parser As New TextFieldParser(reader)

    parser.TextFieldType = FileIO.FieldType.Delimited
    parser.Delimiters = New String() {","}

    Dim row As String()

    While Not parser.EndOfData
        row = parser.ReadFields()

        If row.Length >= 3 Then
            Dim IncidentReport As New ListViewItem()
            IncidentReport.Text = row(0) '
            IncidentReport.SubItems.Add(row(1))
            IncidentReport.SubItems.Add(row(2))

            lstReports.Items.Add(IncidentReport)  
        End If
    End While
End Using
如果您无法使用该版本,则该方法虽然不太好,但仍然比原始方法更好:

lstReports.Items.Clear()

'Load and "Decrypt" the file  
Dim file As String
Using fs As FileStream = File.OpenRead("ReportTitles.txt")
    Dim builder As New StringBuilder(fs.Length)
    For i As Integer = 0 To fs.Length - 1
        'THIS IS NOT ENCRYPTION! At best, it's obfuscation.
        builder.Append(Chr(fs.ReadByte() Xor 22))
    Next
    file = builder.ToString()
End Using

'Use an actual CSV parser
Using reader As New StringReader(file), _
      parser As New TextFieldParser(reader)

    parser.TextFieldType = FileIO.FieldType.Delimited
    parser.Delimiters = New String() {","}

    Dim row As String()

    While Not parser.EndOfData
        row = parser.ReadFields()

        If row.Length >= 3 Then
            Dim IncidentReport As New ListViewItem()
            IncidentReport.Text = row(0) '
            IncidentReport.SubItems.Add(row(1))
            IncidentReport.SubItems.Add(row(2))

            lstReports.Items.Add(IncidentReport)  
        End If
    End While
End Using

在这两种情况下,使用
Try/Catch
而不是
Dir()
检查位置是否存在。试着打开这个文件
Dir()
需要额外的磁盘搜索,而且编程时很少有比磁盘I/O慢的事情。

我们不能为您做多少,因为这主要是一个数据问题。在
If ReportTitles“”上设置一个断点,然后
并检查值或
ReportTitles
以查看您是否得到了预期的结果(即逗号分隔的列表)。
FreeFile
和friends API已过时,不应在新代码中使用。它的存在只是为了在向前移植旧的vb6 era代码时向后兼容。