I am having problems trying to create arrays from text files. The text files created from the program I am working on is like this:

Name Test1 Test2 Test3 Avg Grade
===================================
Student 999 999 999 999 X


The first two lines in this are headings that are added into the text file, and I need the student name, the test scores, avg and grade letter as seperate parts of a structure.

This is for a basic programming class, but the instructor hasn't really gotten into details about how to do this at all. What I have to do with this is search for the student name as you would do in a database to find a student's grade, and we are assuming that we do not know how many students there are in the file.

I am assuming that you would like to view the code I have to see where I am coming from. I have been googling arrays and using MSDN Libraries for help. To view the code, it is between the dashes:

---------------------------------------------------------------------------------
OptionExplicitOn
Imports System.Math
Imports System.IO
Imports System.IO.File
PublicClass Form1
Inherits System.Windows.Forms.Form
Structure StudentRec
Dim Name As String
Dim test1, test2, test3 As Double
Dim Avg As Double
End Structure
Dim AStudents() As StudentRec = {}
Friend max As Integer
Friend pointer As Short
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
btnDisplay.Hide() : btnAccept.Hide() : lstDisplay.Hide() : txtName.Hide() : txtScore1.Hide()
txtScore2.Hide() : txtScore3.Hide() : Label6.Hide() : Label2.Hide() : Label3.Hide() : Label4.Hide()
Label5.Hide() : lblStudentCount.Hide() : btnDisplay.Hide() : btnSave.Hide()
btnDisplay.Enabled = False : btnAccept.Enabled = False : lstDisplay.Enabled = False : txtName.Enabled = False
txtScore1.Enabled = False : txtScore2.Enabled = False : txtScore3.Enabled = False : Label6.Enabled = False
Label2.Enabled = False : Label3.Enabled = False : Label4.Enabled = False : Label5.Enabled = False
lblStudentCount.Enabled = False : btnDisplay.Enabled = False : btnSave.Enabled = False

btnDisplay.Enabled = False
btnAccept.Enabled = False
lblStudentCount.Text = 0
lstDisplay.Items.Add("Name Test 1 Test 2 Test 3 Average Grade")
lstDisplay.Items.Add("==============================================================================================")
End Sub
Private Sub txtName_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtName.Leave
If IsNumeric(txtName.Text) = True Then
txtName.Clear()
txtName.Focus()
MsgBox("I think you were trying to put a test score here, please put the student's name instead")
End If
If txtName.Text = "" Then
txtName.Focus()
End If
End Sub
Private Sub txtScore1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtScore1.Leave
If IsNumeric(txtScore1.Text) = False Then
MsgBox("You need to put the score for the first test")
txtScore1.Clear()
txtScore1.Focus()
Else
If CDbl(txtScore1.Text) > 100 Or CDbl(txtScore1.Text) < 0 Then
MsgBox("The test score is not correct")
txtScore1.Clear()
txtScore1.Focus()
End If
End If
End Sub
Private Sub txtScore2_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtScore2.Leave
If IsNumeric(txtScore2.Text) = False Then
MsgBox("You need to put the score for the second test")
txtScore2.Clear()
txtScore2.Focus()
Else
If CDbl(txtScore2.Text) > 100 Or CDbl(txtScore2.Text) < 0 Then
MsgBox("The test score is not correct")
txtScore2.Clear()
txtScore2.Focus()
End If
End If
btnAccept.Enabled = True
End Sub
Private Sub txtScore3_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtScore3.Leave
If IsNumeric(txtScore3.Text) = False Then
MsgBox("You need to put the score for the third test")
txtScore3.Clear()
txtScore3.Focus()
Else
If CDbl(txtScore3.Text) > 100 Or CDbl(txtScore3.Text) < 0 Then
MsgBox("The test score is not correct")
txtScore3.Clear()
txtScore3.Focus()
End If
End If
End Sub
Private Sub btnAccept_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAccept.Click
lstDisplay.Items.Clear()
lstDisplay.Items.Add("Name Test 1 Test 2 Test 3 Average Grade")
lstDisplay.Items.Add("==============================================================================================")

pointer = 1 + UBound(AStudents)
lblStudentCount.Text = pointer + 1
ReDim Preserve AStudents(pointer)
AStudents(pointer).Name = CStr(txtName.Text)
AStudents(pointer).test1 = CDbl(txtScore1.Text)
AStudents(pointer).test2 = CDbl(txtScore2.Text)
AStudents(pointer).test3 = CDbl(txtScore3.Text)
txtName.Clear()
txtScore1.Clear()
txtScore2.Clear()
txtScore3.Clear()
txtName.Focus()
btnAccept.Enabled = False
btnDisplay.Enabled = True
End Sub
Private Sub btnDisplay_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
lstDisplay.Items.Clear()
lstDisplay.Items.Clear()
lstDisplay.Items.Add("Name Test 1 Test 2 Test 3 Average Grade")
lstDisplay.Items.Add("==============================================================================================")
Dim avg, high, mid, low As Double
Dim Letter As String
For max = 0 To UBound(AStudents)
If AStudents(max).test1 > AStudents(max).test2 And AStudents(max).test1 > AStudents(max).test3 Then
high = AStudents(max).test1
If AStudents(max).test2 > AStudents(max).test3 Then
mid = AStudents(max).test2
low = AStudents(max).test3
Else
mid = AStudents(max).test3
low = AStudents(max).test2
End If
ElseIf AStudents(max).test2 > AStudents(max).test3 Then
high = AStudents(max).test2
If AStudents(max).test1 > AStudents(max).test3 Then
mid = AStudents(max).test1
low = AStudents(max).test3
Else
mid = AStudents(max).test3
low = AStudents(max).test1
End If
Else
high = AStudents(max).test3
If AStudents(max).test1 > AStudents(max).test2 Then
mid = AStudents(max).test1
low = AStudents(max).test2
Else
mid = AStudents(max).test2
low = AStudents(max).test1
End If
End If
avg = ((0.4 * high) + (0.35 * mid) + (0.25 * low))
If avg > 90 Then
Letter = "A"
ElseIf avg > 80 Then
Letter = "B"
ElseIf avg > 70 Then
Letter = "C"
ElseIf avg > 60 Then
Letter = "D"
Else
Letter = "F"
End If
lstDisplay.Items.Add(AStudents(max).Name.PadLeft(1) & AStudents(max).test1.ToString.PadLeft(25) & _
AStudents(max).test2.ToString.PadLeft(15) & AStudents(max).test3.ToString.PadLeft(20) & _
avg.ToString.PadLeft(20) & Letter.PadLeft(20))
Next
btnSave.Enabled = True
End Sub
Private Sub btnExit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExit.Click
End
End Sub
Private Sub btnNew_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnNew.Click
btnDisplay.Show() : btnAccept.Show() : lstDisplay.Show() : txtName.Show() : txtScore1.Show()
txtScore2.Show() : txtScore3.Show() : Label6.Show() : Label2.Show() : Label3.Show() : Label4.Show()
Label5.Show() : lblStudentCount.Show() : btnDisplay.Show() : btnSave.Show()
lstDisplay.Enabled = True : txtName.Enabled = True : txtScore1.Enabled = True
txtScore2.Enabled = True : txtScore3.Enabled = True : Label6.Enabled = True
Label2.Enabled = True : Label3.Enabled = True : Label4.Enabled = True : Label5.Enabled = True
lblStudentCount.Enabled = True : txtName.Focus()
End Sub
Private Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSave.Click
MsgBox("Saving will overwrite old file", MsgBoxStyle.OkOnly)
Dim writer As StreamWriter
writer = New StreamWriter("Grades.txt")
For max = 0 To lstDisplay.Items.Count - 1
writer.WriteLine(lstDisplay.Items.Item(max))
Next
writer.Close()
End Sub
Private Sub btnOpen_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOpen.Click
lstDocument.Items.Clear()
Dim reader As StreamReader
Try
reader = New StreamReader("Grades.txt")
While reader.EndOfStream = False
lstDocument.Items.Add(reader.ReadLine)
End While
reader.Close()
Catch ex As Exception
MsgBox("File does not exist, please create a new file first")
End Try

End Sub
Structure FindStudent
Dim stuName As String
Dim stuTest1, stuTest2, stuTest3, stuAvg As Double
Dim stuGrade As String
End Structure
Private Sub btnSearch_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSearch.Click
Dim stuSearch() As FindStudent = {}
Dim reader As StreamReader = File.OpenText("Grades.txt")
Dim loopcnt As Integer = 0
Dim foundname As String
Dim searchStu As Integer
stuSearch(loopcnt - 1).stuName = reader.ReadLine
Do While stuSearch(loopcnt - 1).stuName = reader.EndOfStream <> False
stuSearch(loopcnt - 1).stuTest1 = reader.ReadLine
stuSearch(loopcnt - 1).stuTest2 = reader.ReadLine
stuSearch(loopcnt - 1).stuTest3 = reader.ReadLine
stuSearch(loopcnt - 1).stuAvg = reader.ReadLine
stuSearch(loopcnt - 1).stuGrade = reader.ReadLine
loopcnt = loopcnt + 1
Loop
foundname = -1
If rdAll.Checked = True And txtNameLookup.Text <> "" Then
For searchStu = 0 To loopcnt
If txtNameLookup.Text = stuSearch(loopcnt).stuName Then
foundname = loopcnt
Exit For
End If
MsgBox("You Entered " & txtNameLookup.Text & " and the person found was " & stuSearch(foundname).stuName)
Next
ElseIf rdFinal.Checked = True And txtNameLookup.Text <> "" Then
For searchStu = 0 To loopcnt
If txtNameLookup.Text = stuSearch(loopcnt).stuName Then
foundname = loopcnt
Exit For
End If
MsgBox("You entered " & txtNameLookup.Text & " and their final grade was " & stuSearch(foundname).stuGrade)
Next
ElseIf rdGrades.Checked = True And txtNameLookup.Text <> "" Then
For searchStu = 0 To loopcnt
If txtNameLookup.Text = stuSearch(loopcnt).stuName Then
foundname = loopcnt
Exit For
End If
MsgBox("You entered " & txtNameLookup.Text & "and their grade letter was " & stuSearch(foundname).stuGrade)
Next
ElseIf rdPercent.Checked = True And txtNameLookup.Text <> "" Then
For searchStu = 0 To loopcnt
If txtName.Text = stuSearch(loopcnt).stuName Then
foundname = loopcnt
Exit For
End If
MsgBox("You entered " & txtName.Text & "and their percentage was " & stuSearch(foundname).stuAvg)
Next
Else
MsgBox("There is an error searching for the student, please try again")
txtName.Clear()
txtName.Focus()
End If
End Sub
EndClass

----------------------------------------------------------
If you have any ideas how to go about this, please let me know because I have been working on this for a very long time, try a week and a half now. To make matters worse, I have to do a similar thing for my linux class using the VIM editor, searching for an animal and then looking up what food it eats using sort, gep, etc without intermediate files and using pipes. I know this is a lot to ask for, but I am so new to this. Thank you in advance for your help.

Recommended Answers

All 16 Replies

Member Avatar

Sorry, I don't see what you're exactly having problems with?

Do you need to create a class for your student grade problem?

I am having problems with creating a second structure/array that data will be read into from a text file. The data is originally written from a listbox if that matters doing a line by line write. The other problem I am having is searching a student's name and trying to get that data from the array just created using the text file. I hope I am answering your question to my question, if not, could you clarify, thank you.

Member Avatar

Each line will be fed into a class structure:

Student 999 999 999 999 X

You would split the line using the space as a delimiter. Look up the split method.

Now you would feed these variables into your class.

I.e

class student
{
     string name
     double  scoreOne
     double  scoreTwo
     double  scoreThree
     double scoreFour
     double average
}

To search for a name you would just look at the name attributes for all your data.

In my programming class, the instructor did discuss this project a little more, and made it sound like it would be easier to put one piece of data on per line, and then reading line by line, but when i do this, it says that the index is out of bounds, even though the first value is 0

To explain my last post, it is the pointer of the structure array that is creating the error. The code that I have is listed below:

--------------------------------------------------------------------------------

count = 0
SearchStudents(count - 1).stuName = reader.ReadLine
Do While SearchStudents(count - 1).stuName <> "-1"
SearchStudents(count - 1).stuTest1 = CDbl(reader.ReadLine)
SearchStudents(count - 1).stuTest2 = CDbl(reader.ReadLine)
SearchStudents(count - 1).stuTest3 = CDbl(reader.ReadLine)
SearchStudents(count - 1).stuAvg = CDbl(reader.ReadLine)
SearchStudents(count - 1).stuGrade = CStr(reader.ReadLine)
count = count + 1
Loop
reader.Close()

---------------------------------------------------------
I have no idea why this is creating the error "IndexOutOfRangeException was unhandled", all I know is that it highlights the second line of code that I have given. The entire project is attached to this post so you could try to find what might really be throwing this error. Again thanks, and so you know, this attached file is newer than the first one that I attached earlier.

Member Avatar

Can you post just the code here. I don't like downloading zip files in case they contains viruses and other known nasties.:cheesy:

A few hints.

'SearchStudents(count - 1).stuName = reader.ReadLine

If that's where the problem is try taking that line out altogether.

SearchStudents(count - 1).

Why the (count - 1). try changing it to SearchStudents(count)

Member Avatar

Another very good tip would be to create a completely new project.

Then just try to read that file into the structure and display it. That way if there are any errors you know it is only to do with that section of code. Trying to do that within a big project is bad, because you don't know if something else is causing the problem.

Isolate and deal with it.

Can you post just the code here. I don't like downloading zip files in case they contains viruses and other known nasties.:cheesy:

in this case, no. a zip file is better because it contains lots of files and some of them contain binary information. Besides, you should always be running a virus scanner which will catch viruses.

Member Avatar

in this case, no. a zip file is better because it contains lots of files and some of them contain binary information. Besides, you should always be running a virus scanner which will catch viruses.

Wrong! All I need is the code and perhaps the text file he's using, then I can compile it from within my IDE. Have you ever used .net before. No it's not like MFC, thank god. :cheesy:

Also while I was away, I was thinking perhaps you're trying to read the whole file into your structure which is allocates space for only five lines.

Here, because some people are worried about viruses, which the files I supply do not contain, I have made them into simple text files. The code is using Visual Studios 2005 (VB). If you have Visual Studios 2005, then rename the This is the text file.txt.txt to "Grades.txt" without the quotes in the "\Visual Studio 2005\Projects\Project 9 - Gradebook option\{Project Name} \bin\Debug\" where {Project Name} is the folder of the project you are creating (if you are). Again thanks for your help. I will also give the files themselves if you need that too.

The form1.vb.txt is really the code, just delete the txt off the extension as this forum does not allow that extension

The form1.designer.vb.txt is the design of the program itself, also delete the txt extension because it is also a vb file. Hope this helps, and I have tried everybody's suggestions, but it doesn't seem to help. Now that you are not afraid of text files, maybe you can investigate the code to see what is wrong (this project is due tomorrow, and I have been working on it for over a week). Thank you guys again.

Member Avatar

Your little error message states:

IndexOutOfRangeException was unhandled",

meaning your array is being accessed beyond it's physical dimension.

Why do you think that is. Try breaking it into smaller chunks.

Wrong! All I need is the code and perhaps the text file he's using, then I can compile it from within my IDE. .

I agree you can do it, but when there are multiple files its just easier to post the .zip file. You can choose to download or not. A virus scanner will take care of any viruses that the zip file may contain. And it saves a lot of time copy the code from the browser and pasting it into my own project.

[edit]the files speterson posted have the same problem(s) as the zip file you dislike so much.[/edit]

The only problem with assigning the index with line numbers manually, is that the user may not know how many students or how many records there might be, but it is suposed to be read in without knowing how long the record file is. The other thing is sometimes, the program brings up other errors (which I do not remember). This is due tomorrow by 8 am central time, and I am really desperate, I thank you guys for your help and ideas though.

Hey everybody,

I finally figured out what was wrong, I got help from the instructor, told him all the problems I was having and that I have tried and was looking all over the place. The solutions to the problems I was having includes the fact that the structure array SearchStudents() has to have at least one pointer, so it needed to be declared as SearchStudents(0). The next problem that I had was that after going through the readline statements, the array had to redim preserve so that it can keep growing each time it goes through the loop. The problem after that is that I needed another priming read after the redimm for the next time around the loop. The final problem I had was when it came to searching this array using a textbox, the loop would keep going through to the end of the array, even if it found the correct student/pointer because the found pointer wasn't saved in another variable, so after saving it to a variable and using that as the pointer to the array, everything else worked just fine, just a little clean up is all that was needed. Hope this makes sense to everybody else. For fun, I will post the project.

I will post it in a couple of ways, so choose, its all the same:

zip file, which contains the project in its entirety, nothing deleted kept out, etc

text file that contains the code I used and another text file that contains a generic gradebook text file

the vb file for the code itself, extension txt has to be deleted, so it is vb and the design for the code which you also have to delete the txt extension to have it in vb.

Member Avatar

Thank you I'm sure that will help somebody else.

I do not care if somebody uses this whole project for an example, but please, if you have the same or a similar project, do not use this code explicitly because I am sure that google will pick this forum up and easy to find where you got the code. Anyways, everybody, enjoy your time, take care.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.