help sorting text file

rowlandsfc

Member
Joined
Feb 3, 2019
Messages
22
Location
bridgend
Programming Experience
Beginner
so i have created a basic game, it has a simple scoring system where the score and player name(both variables) is saved to a text file, leaderboard.text. i have an issue with sorting the file by the score and not the name, i cant get it to work .``

C#:
        // reads the leaderboard txt and displays it in listbox

        private void scoreBoard()

        {

            List<string> lines = File.ReadLines(@"E:\College Year 3\Computer Programming 2\Minefield\Leaderboard.txt").ToList();

            List<int> score = lines.Select(s => Convert.ToInt32(s)).ToList();

            score.Sort();

            foreach (int r in score)

            {

               listBox1.Items.Add(r);

            }



        }

i can supply any other code if needed
thats the code ive tried but i get the error on the list<int> line that it is not in the correct format.

if anyone can steer me in the right direction that would be great
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
The exception of telling you that one of the input lines cannot be converted to an int32 because it is the wrong format. Perhaps you have a blank line, or a line with just letters or punctuation, or a line with a hexadecimal number, etc.

Never use Convert.ToInt32() unless you absolutely trust and control the input. Instead, use int.TryParse().
 

rowlandsfc

Member
Joined
Feb 3, 2019
Messages
22
Location
bridgend
Programming Experience
Beginner
The exception of telling you that one of the input lines cannot be converted to an int32 because it is the wrong format. Perhaps you have a blank line, or a line with just letters or punctuation, or a line with a hexadecimal number, etc.

Never use Convert.ToInt32() unless you absolutely trust and control the input. Instead, use int.TryParse().
Thanks for the reply
I did have int.tryparse initially and that have same error, there isn't any line with just letters or blank lines
The text file is name score
For example
Dan 60
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
Well, the proof is in the putting. Attach your "Leaderboard.txt" file in your next reply.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
it has a simple scoring system where the score and player name(both variables) is saved to a text file, leaderboard.text
What is the format for each line in the file? If a line looks something like:
Code:
Alex 8123487

Then this could would throw the same exception you are currently seeing:
C#:
string line = "Alex 8123487"
int score = Convert.ToInt32(line);

What you need to do is just pull out the number from the line and parse or convert that.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
Serves me right for trying to follow this thread on a phone. I didn't see the sample in post #3.

So it's exactly the issue that I was guessing in post #5. You need to pull the number out of the line before you try to parse or convert it.

My recommendation is to have a class to hold the player's name and score. Something like:
C#:
class PlayerScore
{
    public string Name { get; set; }
    public int Score { get; set; }
}

and the have the following pseudo-code:
Code:
playerScores = new List<PlayerScore>()
foreach line in the score file
    parts = line.Split(' ')
    name = line[0]
    if int.TryParse(line[1], out score) is successful
        playerScores.Add(new PlayerScore() { Name = name, Score = score });

Then once you have your list of players and their scores, it's a simple matter of calling the LINQ OrderByDescending() method to sort things:
C#:
var sortedScores = playerScores.OrderByDescending(playerScore => playerScore.Score).ToList();
 

rowlandsfc

Member
Joined
Feb 3, 2019
Messages
22
Location
bridgend
Programming Experience
Beginner
Serves me right for trying to follow this thread on a phone. I didn't see the sample in post #3.

So it's exactly the issue that I was guessing in post #5. You need to pull the number out of the line before you try to parse or convert it.

My recommendation is to have a class to hold the player's name and score. Something like:
C#:
class PlayerScore
{
    public string Name { get; set; }
    public int Score { get; set; }
}

and the have the following pseudo-code:
Code:
playerScores = new List<PlayerScore>()
foreach line in the score file
    parts = line.Split(' ')
    name = line[0]
    if int.TryParse(line[1], out score) is successful
        playerScores.Add(new PlayerScore() { Name = name, Score = score });

Then once you have your list of players and their scores, it's a simple matter of calling the LINQ OrderByDescending() method to sort things:
C#:
var sortedScores = playerScores.OrderByDescending(playerScore => playerScore.Score).ToList();
sorry for late reply it was quite late where i live lol
thanks for the suggestion will give a go later, i currently have the score and names stored as variables so would it be a case of instead of those variables have that playerScore class? or do you mean, read the text file take the data out of that and then store that into the player class?, sorry pretty new to handling files and arrays lol
 
Last edited:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
A variable can hold only a single value. You said that your leader board file contains multiple names AND scores.

The object oriented way of doing things is to keep related data together. Hence that PlayerScore class to keep the name and score together.

If you were writing code in the 50-60s or were using traditional BASIC, then the old approach was to keep parallel arrays of names and scores. So when you sort by scores, you need to ensure that the names are kept in sync with their corresponding scores. This used to be a standard exercise for people learning C and Pascal before they are taught how to use structures. The exercise is meant to illustrate the pain involved in keeping things in sync.
 

rowlandsfc

Member
Joined
Feb 3, 2019
Messages
22
Location
bridgend
Programming Experience
Beginner
A variable can hold only a single value. You said that your leader board file contains multiple names AND scores.

The object oriented way of doing things is to keep related data together. Hence that PlayerScore class to keep the name and score together.

If you were writing code in the 50-60s or were using traditional BASIC, then the old approach was to keep parallel arrays of names and scores. So when you sort by scores, you need to ensure that the names are kept in sync with their corresponding scores. This used to be a standard exercise for people learning C and Pascal before they are taught how to use structures. The exercise is meant to illustrate the pain involved in keeping things in sync.
I'll give it a go tonight thanks
 

rowlandsfc

Member
Joined
Feb 3, 2019
Messages
22
Location
bridgend
Programming Experience
Beginner
hey thanks for the able i couldnt quite figure out how to get it to work with your supplied code but i have managed to get it working

C#:
string[] hard = File.ReadAllLines(@"E:\College Year 3\Computer Programming 2\Minefield\LeaderboardHard.txt");
                var orderedHard = hard.OrderByDescending(x => int.Parse(x.Split(' ')[1]));

                foreach (var score in orderedHard)
                {
                    listBox1.Items.Add(score);
                }

ive also added a difficulty level so i got it working on the 3 levels now, my only issue with it is the name and score are very close together on the list box, is there a way of styling this and making it look a bit better without messing up the code?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
In WinForms, use a ListView instead of a ListBox. In WPF you would just set the spacing in the XAML and not even touch the code (but that presumes that you are actually using WPF the right way using binding). In WebForms, the correct thing to do is to use a Repeater to populate a table element, but most people "hack" listboxes by inserting non breaking spaces.
 

Napivo

Game Addict
Joined
Oct 17, 2020
Messages
7
Location
Belgium (GMT+1)
Programming Experience
1-3
I wonder what your text file looks like,

If I had to do this, Mine would look like something like this;

Player1; 2000
Player2; 4000
Player3; 5000

Then I could read PlayerName and PlayerScore into a structure and sort the list of structures by points.

Sorry, Admin just new here... Made a mistake.... Post can be deleted
 
Last edited:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
See last line of post #3 to see what the OP's file looks like.
 
Top Bottom