EmPlusPlus
EmPlusPlus

Reputation: 181

How to read duplicate string in a text file in vb.net

I want this program to open a text file and find those specific character and add the words after that into the list (each character has specific subitem in the list). It work well if there is no duplication. But if I have list like:

    /* 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

then it only add the first row. I also make a while loop but it will only add first row to other rows. Is there anyone can help please!(by the way my list include 6 columns )

this is the code:

   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

Upvotes: 2

Views: 1700

Answers (1)

Tim
Tim

Reputation: 28520

By "duplicate strings", I think you mean how to read the file when there is more than one item (group of 6 columns) in the file.

The reason your current program is getting only the first item is because you're exiting the For loop after you find the first occurrence of a given sub item, regardless of how many there may be in the file.

One way to resolve this is to change your sub _Load to a function and have it return a List(Of ListViewItem) object, which you could then iterate through and add to the master list (ListClothes). I would also get rid of the StreamReader, as you don't need it for what you are doing. You're passing the FileName property (which contains the path and extensions) from the OpenFileDialog, so you can simply use that in the _Load function.

It would look something like this:

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

The above code takes the passed in FileName, does a split on the string returned from ReadAllText and removes empty entries.

Next it loops through code, 6 lines at a time. In the loop a new ListViewItem is created, and the sub items are populated, and then this ListViewItem is added to the List(Of ListViewItem).

The populated StockList is then returned.

In your button1_Click event, you could use it like this:

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   

In this code, you pass the selected FileName to the _Load method and assign its return value to the local stockItems variable.

Then you loop through the stockItems list, and add each ListViewItem in it to your clothesList.

NOTE that this code is brittle - if the columns are not in the correct order in the input file, or if a column(s) is/are missing, your data will be skewed, and the program could potentially crash if you try to read a line in the array (from the file) that doesn't exist. Of course, you can wrap that code in a Try Catch block as well.

This is merely one way to do it - I have no doubt there are others. But this should at least get you going in the right direction.

EDIT The easiest way to remove the leading characters is to add them to the split, like this:

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

This will return an array of all the lines, minus empty lines and the leading characters.

Of course, with the code above, you actually don't need those leading characters anymore, as long as the input file always has the columns in the same order.

Upvotes: 2

Related Questions