Reading and Parsing a .txt file (Tab seperated variables)

Craig

Well-known member
Joined
Oct 15, 2005
Messages
110
Location
United Kingdom
Programming Experience
Beginner
Hi, I have a text file that I need to read from here is a small section of it:

id TitleValue First Name Last Name Organisation Address City PostCode Country Work Phone Mobile Phone Fax Number Email Website Team Name No. Competitors No. Spectators Wall Follower Maze Solver Additional Info Competition Enquiry Type Submitted
7 Miss Verona Needham Technology Innovation Centre Contract Compliance & Project AdministrationTechnology Innovation CentreMillennium PointCurzon Street Birmingham B4 7XG United Kingdom 0121 331 7417 0121 331 5401 <e-mail address removed> tic-online.co.uk 0 3 0 0 2004 0 03/02/2004 15:59:01
8 Dr Anthony Wilcox TIC Millennium PointCurzon Street Birmingham B4 7XG United Kingdom 01543 877158 07929 207051 0121 331 5401 <e-mail address removed> micromouse.tic.ac.uk Significance of the PICkle 1 1 1 1 No previous history ... new to competition 2004 0 03/03/2004 09:30:45


Basically, I want to use a multi-dimensional array which will be populated on the form's load event. For example VarArray(0,0) will be 'id' etc

The main issue is being able to seperate each piece of info when it is read from the txt file..

Thanks!
 
Last edited by a moderator:
VB.NET:
Dim splitted() As String = InputString.Split(vbTab)
 
Yes, but the job of splitting all the fields is done and you can put them another place afterwards. From the excerpts above it looks like a header line and each record on its own text line, so it would be easy to process each record by reading the file line by line this way.

Not to argue your methods or intensions, but I would have preferred to create a 'record' structure/class with a member for each field. When processing the file add each 'record' to a one dimensional array/collection. That is object oriented programming, and not abstracting the data by spreading it out in an anonymous multi-dimensional array.
 
JohnH said:
Yes, but the job of splitting all the fields is done and you can put them another place afterwards. From the excerpts above it looks like a header line and each record on its own text line, so it would be easy to process each record by reading the file line by line this way.

Not to argue your methods or intensions, but I would have preferred to create a 'record' structure/class with a member for each field. When processing the file add each 'record' to a one dimensional array/collection. That is object oriented programming, and not abstracting the data by spreading it out in an anonymous multi-dimensional array.


I guess you're right, I was using ReadToEnd, I could just use readline!

I'm not sure what you meant about creating a record structure/class. I am still very new to programming, and this is an assignment for my degree course.. So you'll have to bare with me!

Do you mean make a class and have each column as its own member array eg: Id(), TitleValue(), FirstName() and so on?

Thanks!!
 
Yes, that was what I meant, but in your situation learning the basics is important - so keep up your assignment work!
 
VB.NET:
Dim FileLocation As String = "F:\MicromouseCompetitorsSample.txt"
    Dim SR As StreamReader = New StreamReader(FileLocation)

    Dim Id(50), TitleValue(50), FirstName(50), LastName(50), Organisation(50), Address(50), _
    City(50), PostCode(50), Country(50), WorkPhone(50), MobilePhone(50), FaxNumber(50), Email(50), _
    Website(50), TeamName(50), NumCompetitors(50), NumSpectators(50), WallFollower(50), MazeSolver(50), _
    AdditionalInfo(50), Competition(50), EnquiryType(50), Submitted(50) As String

    Private Sub Frm_Main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim StrText As String
VB.NET:
[SIZE=1]         StrText = SR.ReadLine[/SIZE]
[SIZE=1]         Dim Splitted() As String = StrText.Split(vbTab)
        Dim a, b As Integer

        For a = 0 To Splitted.GetLength(0) - 1

            Id(a) = Splitted(0)
            TitleValue(a) = Splitted(1)
            FirstName(a) = Splitted(2)
            LastName(a) = Splitted(3)
            Organisation(a) = Splitted(4)
            Address(a) = Splitted(5)
            City(a) = Splitted(6)
            PostCode(a) = Splitted(7)
            Country(a) = Splitted(8)
            WorkPhone(a) = Splitted(9)
            FaxNumber(a) = Splitted(10)
            Email(a) = Splitted(11)
            Website(a) = Splitted(12)
            TeamName(a) = Splitted(13)
            NumCompetitors(a) = Splitted(14)
            NumSpectators(a) = Splitted(15)
            WallFollower(a) = Splitted(16)
            MazeSolver(a) = Splitted(17)
            AdditionalInfo(a) = Splitted(18)
            Competition(a) = Splitted(19)
            EnquiryType(a) = Splitted(20)
            Submitted(a) = Splitted(21)
[/SIZE]
VB.NET:
[SIZE=1]            StrText = SR.ReadLine[/SIZE]
[SIZE=1]
        Next

    End Sub
[/SIZE]


I'm still having trouble with this, it puts the same things in all of each of the arrays
 
Last edited:
This is what you do now:
1. open reader
2. read line
3. split line
4. For each field puts it and read an additional line that you don't use


This is what you should do (of this codes standing point)
1. open reader
while sr.Peek <>-1
2. read line
3. split line
4. here insert your For loop to put fields (except the readline!!)
loop
 
There's another problem that has cropped up now!

It shows these strange boxes next to some of the items (see screenshot)

This is my code now:


VB.NET:
 Dim FileLocation As String = "F:\MicromouseCompetitorsSample.txt"
    Dim SR As StreamReader = New StreamReader(FileLocation)

    Dim Id(50), TitleValue(50), FirstName(50), LastName(50), Organisation(50), Address(50), _
    City(50), PostCode(50), Country(50), WorkPhone(50), MobilePhone(50), FaxNumber(50), Email(50), _
    Website(50), TeamName(50), NumCompetitors(50), NumSpectators(50), WallFollower(50), MazeSolver(50), _
    AdditionalInfo(50), Competition(50), EnquiryType(50), Submitted(50) As String

    Private Sub Frm_Main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim StrText As String
        Do While SR.Peek <> -1
            StrText = SR.ReadLine
            Dim Splitted() As String = StrText.Split(vbTab)
            Dim a, b As Integer

            Id(a) = Splitted(0)
            TitleValue(a) = Splitted(1)
            FirstName(a) = Splitted(2)
            LastName(a) = Splitted(3)
            Organisation(a) = Splitted(4)
            Address(a) = Splitted(5)
            City(a) = Splitted(6)
            PostCode(a) = Splitted(7)
            Country(a) = Splitted(8)
            WorkPhone(a) = Splitted(9)
            MobilePhone(a) = Splitted(10)
            FaxNumber(a) = Splitted(11)
            Email(a) = Splitted(12)
            Website(a) = Splitted(13)
            TeamName(a) = Splitted(14)
            NumCompetitors(a) = Splitted(15)
            NumSpectators(a) = Splitted(16)
            WallFollower(a) = Splitted(17)
            MazeSolver(a) = Splitted(18)
            AdditionalInfo(a) = Splitted(19)
            Competition(a) = Splitted(20)
            EnquiryType(a) = Splitted(21)
            Submitted(a) = Splitted(22)

            a += 1
        Loop

        Cb_Choice.Items.Add(Id(0) + vbTab + TitleValue(0) + vbTab + FirstName(0) + vbTab + LastName(0))
        Cb_Choice.SelectedIndex = 0
            Tb_Organisation.Text = Organisation(0)
            Tb_Address.Text = Address(0)
            Tb_City.Text = City(0)
            Tb_PostCode.Text = PostCode(0)
            Tb_Country.Text = Country(0)
            Tb_WorkPhone.Text = WorkPhone(0)
            Tb_MobilePhone.Text = MobilePhone(0)
            Tb_FaxNumber.Text = FaxNumber(0)
            Tb_Email.Text = Email(0)
            Tb_Website.Text = Website(0)
            Tb_TeamName.Text = TeamName(0)
            Tb_NumCompetitors.Text = NumCompetitors(0)
            Tb_NumSpectators.Text = NumSpectators(0)
            Tb_WallFollower.Text = WallFollower(0)
            Tb_MazeSolver.Text = MazeSolver(0)
            Tb_AdditionalInfo.Text = AdditionalInfo(0)
            Tb_Competition.Text = Competition(0)
            Tb_EnquiryType.Text = EnquiryType(0)
            Tb_Submitted.Text = Submitted(0)
 

Attachments

  • screenshot.PNG
    screenshot.PNG
    16.8 KB · Views: 79
Congrats! The strange boxes is the vbTab character you used.
 
You can't. You have to Redim Preserve the arrays.
 
Ok then So I've used Redim, now the problem im having is when if the user changes the location of the text file and i try to reuse the code but now on a different textfile

well this is the code:

VB.NET:
    Dim FileLocation As String = "F:\MicromouseCompetitorsSample.txt"
    Dim SR As StreamReader = New StreamReader(FileLocation)
    Dim SR_LineCount As StreamReader = New StreamReader(FileLocation)

    Dim Id(), TitleValue(), FirstName(), LastName(), Organisation(), Address(), _
    City(), PostCode(), Country(), WorkPhone(), MobilePhone(), FaxNumber(), Email(), _
    Website(), TeamName(), NumCompetitors(), NumSpectators(), WallFollower(), MazeSolver(), _
    AdditionalInfo(), Competition(), EnquiryType(), Submitted() As String
    Dim a, LineCount As Integer
    Private Sub AddRecords()
        CountLines()
        SetArrayVals()
        Populate_ComboBox()
        Cb_Choice.SelectedIndex = 0
        FillFields(Cb_Choice.SelectedIndex + 1)
    End Sub
    Private Sub CountLines()
        LineCount = 0
        Do While SR_LineCount.Peek <> -1
            SR_LineCount.ReadLine()
            LineCount += 1
        Loop
        ReDim Id(LineCount)
        [COLOR=Blue]Shortened to read easier[/COLOR]
        ReDim Submitted(LineCount)

    End Sub
    Private Sub Frm_Main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddRecords()
    End Sub
    Private Sub FillFields(ByVal ArrayPos As Integer)

        Cb_Choice.SelectedIndex = ArrayPos
        [COLOR=Red]Tb_ID.Text = Id(ArrayPos) ***Breaks here: "Index was outside the bounds of the array" [/COLOR]
        Tb_TitleValue.Text = TitleValue(ArrayPos)
        [COLOR=Blue]Shortened to read easier[/COLOR]
        Tb_Submitted.Text = Submitted(ArrayPos)

    End Sub
    Private Sub SetArrayVals()
        a = 0
        Dim StrText As String
        Do While SR.Peek <> -1
            StrText = SR.ReadLine
            Dim Splitted() As String = StrText.Split(vbTab)


            Id(a) = Splitted(0).Trim
            TitleValue(a) = Splitted(1).Trim
            [COLOR=Blue]Shortened to read easier[/COLOR]
            Submitted(a) = Splitted(22).Trim
            a += 1
        Loop
    End Sub
    Private Sub Populate_ComboBox()
        Dim b As Integer
        For b = 0 To LineCount - 1
            Cb_Choice.Items.Add(Id(b) + "     |     " + TitleValue(b) + "     |     " + FirstName(b) + "     |     " + LastName(b))
        Next
    End Sub

    [COLOR=Red]Private Sub Btn_Locate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btn_Locate.Click
        FileDialog.Filter = "Text Files (*.txt)|*.txt"
        FileDialog.ShowDialog()
        FileLocation = FileDialog.FileName
        Lbl_FileLocation.Text = FileLocation
        AddRecords()[/COLOR]
    End Sub
 
About index bounds I don't see an error. Investigate it, see what ArrayPos value it errors out on, check the array length (ID.Length) where appropriate, this is called debugging.

About new file, you must create a new StreamReader, for instance when FileLocation has changed:
VB.NET:
SR = New StreamReader(FileLocation)
 
Back
Top