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