2

我希望这个程序打开一个文本文件并找到那些特定的字符并将之后的单词添加到列表中(每个字符在列表中都有特定的子项)。如果没有重复,它工作得很好。但是,如果我有如下列表:

    /* First row of the list */
#Alireza
%Human
&1
@$1200
$*1
*$1000
   /* ' Second row */
#Behzad
%Human
&1
@$1340
$*1
*$1000
   /* ' And third row */
#Samaneh
%Human
&1
@$1570
$*1
*$1230

然后它只添加第一行。我也做了一个while循环,但它只会将第一行添加到其他行。有没有人可以帮忙!(顺便说一下,我的清单包括 6 列)

这是代码:

   Public code As String
   Public cat As String
   Public stock As Integer
   Public price As Double
   Public sold As Double
   Public cost As Double
   Public i As Integer

Public Sub _Load(ByVal FileName As String)

    Dim strLines() As String
    Dim strLine As String


    Dim strData As String
    Dim objFileInfo As New FileInfo(FileName)

    strData = My.Computer.FileSystem.ReadAllText(FileName)

    strLines = strData.Split(New String() {ControlChars.CrLf}, StringSplitOptions.RemoveEmptyEntries)

        For Each strLine In strLines
            If strLine.StartsWith("#") Then
                code = strLine.Substring(1)

            End If
            strLine = Nothing
        Next

        For Each strLine In strLines
            If strLine.StartsWith("%") Then
                cat = strLine.Substring(1)
                Exit For
            End If
            strLine = Nothing
        Next

        For Each strLine In strLines
            If strLine.StartsWith("&") Then
                stock = strLine.Substring(1)
                Exit For
            End If
            strLine = Nothing
        Next

        For Each strLine In strLines
            If strLine.StartsWith("@$") Then
                price = strLine.Substring(2)
                Exit For
            End If
            strLine = Nothing
        Next

        For Each strLine In strLines
            If strLine.StartsWith("$*") Then
                sold = strLine.Substring(2)
                Exit For
            End If
            strLine = Nothing
        Next

        For Each strLine In strLines
            If strLine.StartsWith("*$") Then
                cost = strLine.Substring(2)
                Exit For
            End If
            strLine = Nothing
        Next
End Sub


Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolImport.Click
    Dim ans As String



    OpenFileDialog1.Title = "What are you looking for?"
    OpenFileDialog1.InitialDirectory = Application.StartupPath
    OpenFileDialog1.Filter = "text Files (*.txt)|*.txt|Data Files (*.dat)|*.dat|All files (*.*)|*.*"
    OpenFileDialog1.FileName = "myList"
    Try
        If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Dim sr As StreamReader = New StreamReader(OpenFileDialog1.FileName)

            Do While sr.Peek > -1
                _Load(OpenFileDialog1.FileName)
                Dim list As New ListViewItem(code)
                list.SubItems.Add(cat)
                list.SubItems.Add(stock)
                list.SubItems.Add(price)
                list.SubItems.Add(sold)
                list.SubItems.Add(cost)
                listClothes.Items.Add(list)
                i += 1
                MessageBox.Show("Your list has been uploaded successfully", "ccc!", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Loop

        End If

    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

End Sub
4

1 回答 1

2

通过“重复字符串”,我认为您的意思是当文件中有多个项目(6 列组)时如何读取文件。

您当前程序仅获得第一项的原因是因为您在For找到给定子项的第一次出现后退出循环,无论文件中可能有多少。

解决此问题的一种方法是将您的 sub 更改_Load为一个函数并让它返回一个List(Of ListViewItem)对象,然后您可以对其进行迭代并添加到主列表 ( ListClothes)。我也会摆脱StreamReader,因为你不需要它来做你正在做的事情。您正在从 传递FileName属性(包含路径和扩展名)OpenFileDialog,因此您可以简单地在_Load函数中使用它。

它看起来像这样:

Public Function _Load(ByVal FileName As String) As List(Of ListViewItem)

    Dim Lines() As String
    Dim List(Of ListViewItem) StockList = New List(Of ListViewItem)
    Dim ListViewItem As StockItem    

    Lines = File.ReadAllText(FileName).Split(New String() _
                 { ControlChars.CrLf}, StringSplitOptions.RemoveEmptyEntries)

    For j = 0 To Lines.Length - 1 Step 6    

        StockItem = New ListViewItem(Lines(j))
        StockItem.SubItems.Add(Lines(j + 1))
        StockItem.SubItems.Add(Lines(J + 2))
        StockItem.SubItems.Add(Lines(j + 3))
        StockItem.SubItems.Add(Lines(J + 4))
        StockItem.SubItems.Add(Lines(j + 5))  

        StockList.Add(StockItem)
    Next

    Return StockList
End Function

上面的代码采用传入的FileName,对从返回的字符串进行拆分ReadAllText并删除空条目。

接下来它循环代码,一次 6 行。在循环中创建了一个新的 ListViewItem,并填充了子项,然后将此 ListViewItem 添加到List(Of ListViewItem).

StockList然后返回填充的。

在您的button1_Click活动中,您可以像这样使用它:

Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolImport.Click

    Dim ans As String
    Dim stockItems As List(Of ListViewItem)

    OpenFileDialog1.Title = "What are you looking for?"
    OpenFileDialog1.InitialDirectory = Application.StartupPath
    OpenFileDialog1.Filter = "text Files (*.txt)|*.txt|Data Files (*.dat)|*.dat|All files (*.*)|*.*"
    OpenFileDialog1.FileName = "myList"

    Try
        If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            stockItems = _Load(OpenFileDialog1.FileName)

            For Each (stockItem As ListViewItem in stockItems)
                listClothes.Add(stockItem)
            Next

            MessageBox.Show("Your list has been uploaded successfully", "ccc!", MessageBoxButtons.OK, MessageBoxIcon.Information)
         End If
     Catch ex As Exception
         MsgBox(ex.Message)
     End Try
End Sub   

在此代码中,您将所选内容传递FileName_Load方法并将其返回值分配给局部stockItems变量。

然后循环遍历stockItems列表,并将其中的每个添加ListViewItem到您的clothesList.

请注意,此代码很脆弱 - 如果输入文件中的列顺序不正确,或者缺少列,则您的数据将出现偏差,并且如果您尝试读取程序可能会崩溃数组中的一行(来自文件)不存在。当然,您也可以将该代码包装在 Try Catch 块中。

这只是一种方法——我毫不怀疑还有其他方法。但这至少应该让你朝着正确的方向前进。

编辑 删除前导字符的最简单方法是将它们添加到拆分中,如下所示:

Lines = File.ReadAllText(FileName).Split(New String() _
             { ControlChars.CrLf, "#", "%", "&", "@$", "$*", "*$"}, _
              StringSplitOptions.RemoveEmptyEntries)

这将返回所有行的数组,减去空行和前导字符。

当然,使用上面的代码,您实际上不再需要那些前导字符,只要输入文件始终具有相同顺序的列。

于 2013-08-05T06:53:00.500 回答