Splitting a .txt file and sorting it
-
Experts, Initally what i want to do is to sort 2 lots of data. 1 sort would be the highscore (the highest of the score, ad the second dort would be through the time (lowest). I dont't really know what the best way to do this, so that was why i thought i would ask you lot. I also will post up the code i am having a bit of trouble with. This may be able to cope with what i am wanting to do. I am using 1 button called comtest 2 list boxes called listBox1 and ListBox2 2 textboxes called text1 and text2
Imports System.IO
Public Class Form1
Dim scores = New System.Collections.Generic.List(Of String)
Dim names = New System.Collections.Generic.List(Of String)
Dim test1(0 To 10) As String
Dim test2(0 To 10) As Integer
Dim userscore As Integer
Dim username As String
Dim a As Integer
Dim b As Integer
Dim i As Integer
Dim strFilename As String = ("High Scores.txt")Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call highscore() names = New System.Collections.Generic.List(Of String) scores = New System.Collections.Generic.List(Of Integer) Dim srScores As New IO.StreamReader(strFilename) While Not srScores.EndOfStream Dim strRead As String = srScores.ReadLine ListBox1.Items.Add(strRead) Dim strSplit() As String = Split(strRead, ",") names.Add(strSplit(0)) scores.Add(strSplit(1)) End While srScores.Close() End Sub
Private Sub comtest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comtest.Click
username = Text1.Text
userscore = Val(Text2.Text)
For i = 1 To 10
a = scores(i)
If userscore >= a Then
test1(i) = username
test2(i) = userscore
For b = i + 1 To 10
test1(b) = names(b - 1)
test2(b) = scores(b - 1)
Next
Call newscore()
Exit Sub
End If
test1(i) = names(i)
test2(i) = scores(i)
Next
End Sub
Private Sub highscore()
For i = 1 To 10
ListBox1.Items.Add(names(i)) 'this always comes up with an error saying argument out of range
List2.Items.Add(scores(i))
Next
End Sub
Private Sub newscore() ' write
ListBox1.ClearSelected()
List2.ClearSelected()
For i = 1 To 10
ListBox1.Items.Add(test1(i)) -
Experts, Initally what i want to do is to sort 2 lots of data. 1 sort would be the highscore (the highest of the score, ad the second dort would be through the time (lowest). I dont't really know what the best way to do this, so that was why i thought i would ask you lot. I also will post up the code i am having a bit of trouble with. This may be able to cope with what i am wanting to do. I am using 1 button called comtest 2 list boxes called listBox1 and ListBox2 2 textboxes called text1 and text2
Imports System.IO
Public Class Form1
Dim scores = New System.Collections.Generic.List(Of String)
Dim names = New System.Collections.Generic.List(Of String)
Dim test1(0 To 10) As String
Dim test2(0 To 10) As Integer
Dim userscore As Integer
Dim username As String
Dim a As Integer
Dim b As Integer
Dim i As Integer
Dim strFilename As String = ("High Scores.txt")Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call highscore() names = New System.Collections.Generic.List(Of String) scores = New System.Collections.Generic.List(Of Integer) Dim srScores As New IO.StreamReader(strFilename) While Not srScores.EndOfStream Dim strRead As String = srScores.ReadLine ListBox1.Items.Add(strRead) Dim strSplit() As String = Split(strRead, ",") names.Add(strSplit(0)) scores.Add(strSplit(1)) End While srScores.Close() End Sub
Private Sub comtest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comtest.Click
username = Text1.Text
userscore = Val(Text2.Text)
For i = 1 To 10
a = scores(i)
If userscore >= a Then
test1(i) = username
test2(i) = userscore
For b = i + 1 To 10
test1(b) = names(b - 1)
test2(b) = scores(b - 1)
Next
Call newscore()
Exit Sub
End If
test1(i) = names(i)
test2(i) = scores(i)
Next
End Sub
Private Sub highscore()
For i = 1 To 10
ListBox1.Items.Add(names(i)) 'this always comes up with an error saying argument out of range
List2.Items.Add(scores(i))
Next
End Sub
Private Sub newscore() ' write
ListBox1.ClearSelected()
List2.ClearSelected()
For i = 1 To 10
ListBox1.Items.Add(test1(i))There are several problems in your program - you defined
names = New System.Collections.Generic.List(Of String)
in the declarations section and later on in Form_Load you havescores = New System.Collections.Generic.List(Of Integer)
. Is the list of type Integer or String? - you are trying to load the listboxes with names/scores before you read them from the textfile. so move the lineCall highscore
to the bottom in Form1_Load - inSub highscore
you are loading the listboxes from the names/scores lists. The entries in the list are indexed from 0 to Count-1. So change the first line toFor i = 0 To 9
there are probably several more problems but this should get you started.Tosch
-
There are several problems in your program - you defined
names = New System.Collections.Generic.List(Of String)
in the declarations section and later on in Form_Load you havescores = New System.Collections.Generic.List(Of Integer)
. Is the list of type Integer or String? - you are trying to load the listboxes with names/scores before you read them from the textfile. so move the lineCall highscore
to the bottom in Form1_Load - inSub highscore
you are loading the listboxes from the names/scores lists. The entries in the list are indexed from 0 to Count-1. So change the first line toFor i = 0 To 9
there are probably several more problems but this should get you started.Tosch
Thanks a million Tosch. It is really annoying when you spot stupid mistakes like that. I am still getting an error on under the sub heading highscores on listBox1.Items.Add(names(i)) The error is ArgumentOutOfRangeException was unhandled? AND the index was out of range. must be non-negative and less than the size of the collection. Parameter name:index Any ideas Cheers Dan
modified on Wednesday, April 14, 2010 9:57 AM
-
Thanks a million Tosch. It is really annoying when you spot stupid mistakes like that. I am still getting an error on under the sub heading highscores on listBox1.Items.Add(names(i)) The error is ArgumentOutOfRangeException was unhandled? AND the index was out of range. must be non-negative and less than the size of the collection. Parameter name:index Any ideas Cheers Dan
modified on Wednesday, April 14, 2010 9:57 AM
-
Change the
For...
to theFor i = 0 to names.count - 1
. Do you have exactly 10 names/scores in your textfile? Otherwise you try to display 10 entries in the names list even if there are less entries.Tosch
WOOOOOO it actually seems to work. Quick question though I tried to trick the code to see if the sort is actually working and it doesn't appear to sort the highscores into numerical order. All i actually done was just move the highest score to the bottom of the text file, so only one of them was out of sync. There also seems to be an error on button click, which i think is part of the sorting.
Private Sub comtest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comtest.Click
username = Text1.Text
userscore = Val(Text2.Text)
For i = 1 To 10
a = scores(i)
If userscore >= a Then
test1(i) = username
test2(i) = userscore
For b = i + 1 To 10
test1(b) = names(b - 1) ' comes up with an error saying ArgumentOutOfRage index was out of range, must be non-negative
test2(b) = scores(b - 1)
Next
Call newscore()
Exit Sub
End If
test1(i) = names(i)
test2(i) = scores(i)
Next
End SubAny ideas Many thanks for all the help Cheers Dan
modified on Wednesday, April 14, 2010 10:46 AM
-
WOOOOOO it actually seems to work. Quick question though I tried to trick the code to see if the sort is actually working and it doesn't appear to sort the highscores into numerical order. All i actually done was just move the highest score to the bottom of the text file, so only one of them was out of sync. There also seems to be an error on button click, which i think is part of the sorting.
Private Sub comtest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comtest.Click
username = Text1.Text
userscore = Val(Text2.Text)
For i = 1 To 10
a = scores(i)
If userscore >= a Then
test1(i) = username
test2(i) = userscore
For b = i + 1 To 10
test1(b) = names(b - 1) ' comes up with an error saying ArgumentOutOfRage index was out of range, must be non-negative
test2(b) = scores(b - 1)
Next
Call newscore()
Exit Sub
End If
test1(i) = names(i)
test2(i) = scores(i)
Next
End SubAny ideas Many thanks for all the help Cheers Dan
modified on Wednesday, April 14, 2010 10:46 AM
Sorting in the listbox won't work because it sorts the entries as strings and not in numerical order. So it sorts like 10,100,11 and so on. This is a bit tricky to solve. You could padd left the scores with 0. The scores would then be 010,100,011 which would sort correctly. Try to google for a solution to this. There are a number of options you have. Same problem in your code with the amount of entries in names list? Try
...To names/scores.count-1
instead of..To 10
Tosch
-
Experts, Initally what i want to do is to sort 2 lots of data. 1 sort would be the highscore (the highest of the score, ad the second dort would be through the time (lowest). I dont't really know what the best way to do this, so that was why i thought i would ask you lot. I also will post up the code i am having a bit of trouble with. This may be able to cope with what i am wanting to do. I am using 1 button called comtest 2 list boxes called listBox1 and ListBox2 2 textboxes called text1 and text2
Imports System.IO
Public Class Form1
Dim scores = New System.Collections.Generic.List(Of String)
Dim names = New System.Collections.Generic.List(Of String)
Dim test1(0 To 10) As String
Dim test2(0 To 10) As Integer
Dim userscore As Integer
Dim username As String
Dim a As Integer
Dim b As Integer
Dim i As Integer
Dim strFilename As String = ("High Scores.txt")Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call highscore() names = New System.Collections.Generic.List(Of String) scores = New System.Collections.Generic.List(Of Integer) Dim srScores As New IO.StreamReader(strFilename) While Not srScores.EndOfStream Dim strRead As String = srScores.ReadLine ListBox1.Items.Add(strRead) Dim strSplit() As String = Split(strRead, ",") names.Add(strSplit(0)) scores.Add(strSplit(1)) End While srScores.Close() End Sub
Private Sub comtest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comtest.Click
username = Text1.Text
userscore = Val(Text2.Text)
For i = 1 To 10
a = scores(i)
If userscore >= a Then
test1(i) = username
test2(i) = userscore
For b = i + 1 To 10
test1(b) = names(b - 1)
test2(b) = scores(b - 1)
Next
Call newscore()
Exit Sub
End If
test1(i) = names(i)
test2(i) = scores(i)
Next
End Sub
Private Sub highscore()
For i = 1 To 10
ListBox1.Items.Add(names(i)) 'this always comes up with an error saying argument out of range
List2.Items.Add(scores(i))
Next
End Sub
Private Sub newscore() ' write
ListBox1.ClearSelected()
List2.ClearSelected()
For i = 1 To 10
ListBox1.Items.Add(test1(i))- Gotta get used to zero-indexed arrays/lists... In programming, everything starts at zero (Once you get beyond VB6)... An array or list with 10 elements actually goes from 0 to 9. There's no element #10 (That would be the 11th element). If you count from 1 to 10, you skip the first element (0) and go past the last element (9). 2) When you're using the .NET framework, try not to reinvent the wheel. You shouldn't have to write your own sorting routine in most cases, because the framework already has those kinds of things built-in. 3) Try to think in terms of objects, not simple arrays. You're working with these things as arrays of strings and integers, when you're really dealing with high scores, each of which has a name and a value. You need to put them together so you can work with them more easily... That requires a class or structure...
Public Class HighScore
Dim Name As String
Dim Score As Integer
End Class- Once you put them together like this, it's a lot easier to shuffle them around as needed. If you have a
List(Of HighScore)
, you can even automate the sorting by just calling the Sort() function. The only trick there is that you have to tell it how a HighScore should be sorted:
Public Class HighScore
Implements System.IComparable(Of HighScore)Dim Name As String
Dim Score As IntegerPublic Function CompareTo(ByVal other As HighScore) As Integer
CompareTo = -Score.CompareTo(other.Score)
End Function
End ClassNow a HighScore object knows that it should be sorted by score. Since we negate the result in the CompareTo function, it puts it in descending order instead of ascending order. When you tell the list to Sort(), it'll know what to do. 5) But then, you want to ALWAYS have it sorted, right? Well, the framework can do that too... Instead of a
List(Of HighScore)
, try using aSortedList(Of HighScore)
. Then you don't have to do any work at all... When you add the new score in, it'll automatically jump to the right spot. 6) As for displaying them... Well, ListBoxes are pretty smart too... Now it's been a while since I've worked with WinForms (WPF is the new way to do things), but if I remember right, ListBoxes have a "DisplayMember" property. In this case, you can just set the DisplayMember of the two lists to "Name" and "Score" respectively, and then just add the HighScore objects to them. If the DisplayMember is "Name", the control will look for a "Name" property on the object you -
- Gotta get used to zero-indexed arrays/lists... In programming, everything starts at zero (Once you get beyond VB6)... An array or list with 10 elements actually goes from 0 to 9. There's no element #10 (That would be the 11th element). If you count from 1 to 10, you skip the first element (0) and go past the last element (9). 2) When you're using the .NET framework, try not to reinvent the wheel. You shouldn't have to write your own sorting routine in most cases, because the framework already has those kinds of things built-in. 3) Try to think in terms of objects, not simple arrays. You're working with these things as arrays of strings and integers, when you're really dealing with high scores, each of which has a name and a value. You need to put them together so you can work with them more easily... That requires a class or structure...
Public Class HighScore
Dim Name As String
Dim Score As Integer
End Class- Once you put them together like this, it's a lot easier to shuffle them around as needed. If you have a
List(Of HighScore)
, you can even automate the sorting by just calling the Sort() function. The only trick there is that you have to tell it how a HighScore should be sorted:
Public Class HighScore
Implements System.IComparable(Of HighScore)Dim Name As String
Dim Score As IntegerPublic Function CompareTo(ByVal other As HighScore) As Integer
CompareTo = -Score.CompareTo(other.Score)
End Function
End ClassNow a HighScore object knows that it should be sorted by score. Since we negate the result in the CompareTo function, it puts it in descending order instead of ascending order. When you tell the list to Sort(), it'll know what to do. 5) But then, you want to ALWAYS have it sorted, right? Well, the framework can do that too... Instead of a
List(Of HighScore)
, try using aSortedList(Of HighScore)
. Then you don't have to do any work at all... When you add the new score in, it'll automatically jump to the right spot. 6) As for displaying them... Well, ListBoxes are pretty smart too... Now it's been a while since I've worked with WinForms (WPF is the new way to do things), but if I remember right, ListBoxes have a "DisplayMember" property. In this case, you can just set the DisplayMember of the two lists to "Name" and "Score" respectively, and then just add the HighScore objects to them. If the DisplayMember is "Name", the control will look for a "Name" property on the object youWOW thanks, However i am having a few probelms, the
Ian Shlasko wrote:
SortedList(Of HighScore)
doesn't seem to work, I have put this code under a button click and it comes up with an error saying "no accessible 'sorted list' accepts this number of type arguments"? I am really grateful of the time you put in explaining in depth what is needed, it was just strange that it ain't working. I am using vb.net 2005, in normal design mode (not in console) if thats any help :)
-
WOW thanks, However i am having a few probelms, the
Ian Shlasko wrote:
SortedList(Of HighScore)
doesn't seem to work, I have put this code under a button click and it comes up with an error saying "no accessible 'sorted list' accepts this number of type arguments"? I am really grateful of the time you put in explaining in depth what is needed, it was just strange that it ain't working. I am using vb.net 2005, in normal design mode (not in console) if thats any help :)
Oh right, I always forget that... The SortedList takes two arguments, so it would be
SortedList(Of Integer, HighScore)
(Can't remember if that's the exact syntax, as I usually code in C#). When you add something to it, you'd do.Add(item.Score, item)
, so it knows to sort it by the score.Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels) -
Oh right, I always forget that... The SortedList takes two arguments, so it would be
SortedList(Of Integer, HighScore)
(Can't remember if that's the exact syntax, as I usually code in C#). When you add something to it, you'd do.Add(item.Score, item)
, so it knows to sort it by the score.Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels)hmmmm there seems to be something not right with the code. I dont have to define SortedList of anything like that, as it still doesn't like
Ian Shlasko wrote:
SortedList(Of Integer, HighScore)
I really am grateful for all the help Dan
-
hmmmm there seems to be something not right with the code. I dont have to define SortedList of anything like that, as it still doesn't like
Ian Shlasko wrote:
SortedList(Of Integer, HighScore)
I really am grateful for all the help Dan
Make sure you're working with the one in System.Collections.Generics. There's a generic and regular version.
Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels)