在c#中写入文本文件,但当它在网格中显示时,相同的信息会重复

在c#中写入文本文件,但当它在网格中显示时,相同的信息会重复,c#,datagridview,foreach,file-writing,C#,Datagridview,Foreach,File Writing,所以我用c#创建了一个测验(只是为了好玩和学习) 在我的高分表格中,来自playerdetails类的信息显示了同一玩家的5次,而不是一次。见代码: public frmHighscore() { InitializeComponent(); //Only save the test scores once if (!File.Exists("highscores.txt")) { SaveScor

所以我用c#创建了一个测验(只是为了好玩和学习) 在我的高分表格中,来自playerdetails类的信息显示了同一玩家的5次,而不是一次。见代码:

public frmHighscore()
    {
        InitializeComponent();

        //Only save the test scores once
        if (!File.Exists("highscores.txt"))
        {
            SaveScores();
        }

        LoadScores();
        //Sort the grid based on the value of Column 1 which will be the score value
        dataGridView1.Sort(dataGridView1.Columns[1], ListSortDirection.Descending);
    }

    private void SaveScores()
    {
        //Open filestram and streamwriter needed to save details to a text file
        FileStream fileStream = new FileStream("highscores.txt", FileMode.Append, FileAccess.Write);
        StreamWriter streamWriter = new StreamWriter(fileStream);

        try
        {
            //loop over each player

            {
                //Write details of the player to the textfile in format playerName~Score
                foreach (Player player in PlayerList)
                {
                    streamWriter.WriteLine(player.playerName + "~" + player.playerScore);
                }
            }
        }
        catch (Exception)
        {
            MessageBox.Show("Error loading the scores", "Please try again");
        }
        finally
        {
            //close streamwriter and filestream
            streamWriter.Close();
            fileStream.Close();
        }
    }

    private void LoadScores()
    {
        //Check if the file exists
        if (File.Exists("highscores.txt"))
        {
            //Read in all the details of the text file
            var playerScores = File.ReadAllLines("highscores.txt");

            //check if players exist in the text file
            if (playerScores.Length > 0)
            {
                //Loop over each player details
                foreach (var playerScore in playerScores)
                {
                    //Add the player name and score to the datagrid
                    var splitDetails = playerScore.Split('~');
                    dataGridView1.Rows.Add(splitDetails[0], Convert.ToInt32(splitDetails[1]));
                }
            }
            else
            {
                //Hide the grid and show the No Scores label
                HideGrid();
            }
        }
我的播放器类如下所示: 命名空间测试

{
       public class Player
{
    public string Username;
    public int Score;
    public int quizNumber;

    public string playerName { get; set; }
    public  int playerScore { get; set; }

    public static List<Player> player = new List<Player>();


    public Player(string name)
    {
        Username = name;
        Score = 0;
    }

}
}
{
公开课选手
{
公共字符串用户名;
公众智力得分;
基兹努伯公共酒店;
公共字符串播放器名称{get;set;}
public int playerScore{get;set;}
公共静态列表播放器=新列表();
公共播放器(字符串名称)
{
用户名=名称;
得分=0;
}
}
}

如果
player
变量是我假设的,那么

streamWriter.WriteLine(PlayerDetails.playerName + "~" + PlayerDetails.playerScore);
应该是

streamWriter.WriteLine(player.playerName + "~" + player.playerScore);

如果
player
变量是我假设的,那么

streamWriter.WriteLine(PlayerDetails.playerName + "~" + PlayerDetails.playerScore);
应该是

streamWriter.WriteLine(player.playerName + "~" + player.playerScore);

如果如您所说的
PlayerDetails.playerName
类型为
string
,则您正在循环一个
字符串,该字符串有6个字符,每次打印相同的信息时:

PlayerDetails.playerName+“~”+PlayerDetails.playerScore
=>name~6

这就是为什么你得到6行

如果您只想打印当前玩家的姓名和分数,则只需在不使用循环的情况下使用即可:

streamWriter.WriteLine(PlayerDetails.playerName + "~" + PlayerDetails.playerScore);
如果你想在游戏中有多个玩家 我建议使用适当的结构来保存玩家的信息。拥有一个包含您所有信息(您可能已经拥有)的类
Player

还有一个像
List
这样的集合,包含所有玩家。然后,您将循环浏览玩家列表,并使用迭代变量
player
访问每个玩家的属性

List<Player> PlayerList = new List<Player>();

PlayerList.Add(new Player(){playerName = "Alfred", playerScore = 0});

// start the game
//...

// write down the results of all players
foreach (Player player in PlayerList)
{
    streamWriter.WriteLine(player.playerName + "~" + player.playerScore);
}
表示每个项并允许您访问其属性。在您的例子中,
集合
是一个由
字符组成的
字符串
将代表该字符串中的每个字符

编辑

1) 问题是您将值添加到了类中:

public string playerName { get; set; }
public  int playerScore { get; set; }
但你从不给他们赋值。在构造函数中,您仍然仅初始化:

Username = name;
Score = 0;
所以你也应该使用这些值<代码>用户名
和分数
在for循环中

2) 下一个问题是
PlayerList
不属于类
Player
。它不是玩家的财产,而是游戏的财产,所以它应该是游戏发生的地方。因为在那里你也会把想要玩的玩家添加到列表中。把它想象成一个真实的场景。在类
frmHighscore
中,您希望循环通过
PlayerList

foreach (Player player in PlayerList)
{
    streamWriter.WriteLine(player.playerName + "~" + player.playerScore);
}
但是我没有看到这个变量的任何声明。编译器应该对此抱怨,因为它找不到它。你需要在那里加上这个。也可以在这个类中填充它,或者从初始化玩家并将他们添加到列表的类中传递一个引用


我希望您现在能更好地理解它。

如果正如您所说的
PlayerDetails.playerName
string
类型,那么您正在循环一个
string
,它有6个字符,每次打印相同的信息:

PlayerDetails.playerName+“~”+PlayerDetails.playerScore
=>name~6

这就是为什么你得到6行

如果您只想打印当前玩家的姓名和分数,则只需在不使用循环的情况下使用即可:

streamWriter.WriteLine(PlayerDetails.playerName + "~" + PlayerDetails.playerScore);
如果你想在游戏中有多个玩家 我建议使用适当的结构来保存玩家的信息。拥有一个包含您所有信息(您可能已经拥有)的类
Player

还有一个像
List
这样的集合,包含所有玩家。然后,您将循环浏览玩家列表,并使用迭代变量
player
访问每个玩家的属性

List<Player> PlayerList = new List<Player>();

PlayerList.Add(new Player(){playerName = "Alfred", playerScore = 0});

// start the game
//...

// write down the results of all players
foreach (Player player in PlayerList)
{
    streamWriter.WriteLine(player.playerName + "~" + player.playerScore);
}
表示每个项并允许您访问其属性。在您的例子中,
集合
是一个由
字符组成的
字符串
将代表该字符串中的每个字符

编辑

1) 问题是您将值添加到了类中:

public string playerName { get; set; }
public  int playerScore { get; set; }
但你从不给他们赋值。在构造函数中,您仍然仅初始化:

Username = name;
Score = 0;
所以你也应该使用这些值<代码>用户名
和分数在for循环中

2) 下一个问题是
PlayerList
不属于类
Player
。它不是玩家的财产,而是游戏的财产,所以它应该是游戏发生的地方。因为在那里你也会把想要玩的玩家添加到列表中。把它想象成一个真实的场景。在类
frmHighscore
中,您希望循环通过
PlayerList

foreach (Player player in PlayerList)
{
    streamWriter.WriteLine(player.playerName + "~" + player.playerScore);
}
但是我没有看到这个变量的任何声明。编译器应该对此抱怨,因为它找不到它。你需要在那里加上这个。也可以在这个类中填充它,或者从初始化玩家并将他们添加到列表的类中传递一个引用


我希望您现在能更好地理解它。

foreach(PlayerDetails中的var-player)streamWriter.WriteLine(player.playerName+“~”+player.playerScore);}什么类型是
PlayerDetails.playerName
?它是字符串类型foreach(PlayerDetails中的var player)streamWriter.WriteLine(player.playerName+“~”+player.playerScore);}什么类型是
PlayerDetails.playerName
?根据OP
PlayerDetails的注释,它是字符串类型。playerName
string
,因此
player
将是
char
,编译器会根据OP的注释抱怨它找不到属性
playerName
PlayerDetails.playerName
是一个
strin