在c#中写入文本文件,但当它在网格中显示时,相同的信息会重复
所以我用c#创建了一个测验(只是为了好玩和学习) 在我的高分表格中,来自playerdetails类的信息显示了同一玩家的5次,而不是一次。见代码:在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
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
?根据OPPlayerDetails的注释,它是字符串类型。playerName
是string
,因此player
将是char
,编译器会根据OP的注释抱怨它找不到属性playerName
PlayerDetails.playerName
是一个strin