C# 如何让程序访问数据文件以输出平均分数和最高分数以及建议的班级数据?如何减轻按钮1单击中的错误?
我的任务是编写一个程序,访问包含篮球运动员姓名和分数的外部文本文件。无论使用何种语言,我在从txt文件读写时总是遇到问题。一旦txt文件被读取,程序就应该输出所有玩家的平均分数以及得分最高的玩家的名字。以下是我所拥有的:C# 如何让程序访问数据文件以输出平均分数和最高分数以及建议的班级数据?如何减轻按钮1单击中的错误?,c#,average,streamreader,streamwriter,C#,Average,Streamreader,Streamwriter,我的任务是编写一个程序,访问包含篮球运动员姓名和分数的外部文本文件。无论使用何种语言,我在从txt文件读写时总是遇到问题。一旦txt文件被读取,程序就应该输出所有玩家的平均分数以及得分最高的玩家的名字。以下是我所拥有的: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; us
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
namespace TextFiles
{
public partial class BasketBallStats : Form
{
List<int> marks = new List<int>();
public BasketBallStats()
{
InitializeComponent();
}
// Form load event handler used to construct
// object of the Streamwriter class, sending the
// new filename as an argument. Enclosed in
// try...catch block.
public class BasketballController
{
public class Entry
{
public int Value { get; set; }
public string Name { get; set; }
}
BasketballController(string filename)
{
this.filename = filename;
}
private string filename;
private List<Entry> data = new List<Entry>();
public List<Entry> Data
{
get
{
// Clear data
data.Clear();
// Iterate through lines
foreach (string line in System.IO.File.ReadLines(filename))
{
// Split by space
List<string> parts = line.Trim().Split(' ').ToList();
if (parts.Count() < 2)
continue;
// Number is last space separated string
int number = int.Parse(parts.Last());
// Remove number
parts.RemoveAt(parts.Count() - 1);
// Name is any previous word joined by space
string name = string.Join(" ", parts).Trim();
// Add number and name to data
data.Add(new Entry() { Name = name, Value = number });
}
// Sort from greater value to smaller
data.Sort(Comparer<Entry>.Create(
(l, r) => r.Value.CompareTo(l.Value)));
return data;
}
set
{
using (var writer = new System.IO.StreamWriter(filename))
{
foreach (var entry in value)
{
writer.WriteLine(string.Format("{0} {1}", entry.Name, entry.Value));
}
}
data = value;
}
}
public double Average
{
get
{
// Read file if data is empty, otherwise reuse its value
var src = (data.Count() == 0) ? Data : data;
if (src.Count() == 0)
return 0.0;
// Return average
return src.Average(x => x.Value);
}
}
}
private string score;
public List<int> Marks { get => Marks1; set => Marks1 = value; }
public List<int> Marks1 { get => marks; set => marks = value; }
private void BasketBallStats_Load(object sender, EventArgs e)
{
}
private void BtnCreateFile_Click(object sender, EventArgs e)
{
score = "basketBallScore.txt";
if (File.Exists(score))
{
Console.WriteLine("FileName: {0}", score);
Console.WriteLine("Attributes: {0}",
File.GetAttributes(score));
Console.WriteLine("Created: {0}",
File.GetCreationTime(score));
Console.WriteLine("Last Accessed: {0}",
File.GetLastAccessTime(score));
DirectoryInfo dir = new DirectoryInfo(".");
Console.WriteLine("Current Directory: \n{0} \n",
Directory.GetCurrentDirectory());
Console.WriteLine("File Name".PadRight(52) +
"Size".PadRight(10) + "Creation Time");
foreach (FileInfo fil in dir.GetFiles("*.*"))
{
string name = fil.Name;
long size = fil.Length;
DateTime creationTime = fil.CreationTime;
Console.WriteLine("{0} {1,12:NO} {2, 20:g} ", name.PadRight(45),
size, creationTime);
}
}
else
{
Console.WriteLine("{0} not found - using current" +
"directory:", score);
}
Console.ReadKey();
}
private void BtnWriteFile_Click(object sender, EventArgs e)
{
try
{
var WriteToFile = new System.IO.StreamWriter("basketBallScore.txt"); //create textfile in default directory
WriteToFile.Write(listView1.Text + ", " + listView1.Text + ", " + listView1.Text + ", " + listView1.Text);
WriteToFile.Close();
Marks.Add(Convert.ToInt32(listView1.Text)); //add to list
}
catch (System.IO.DirectoryNotFoundException)
{
lblMessage.Text = "File did not close properly: "; //add error message
}
}
private void ManipulateFile_Click(object sender, EventArgs e)
{
int[] hoursArray = new int[30];
StreamReader fileSR = new StreamReader("basketBallScore.txt");
int counter = 0;
string line = "";
line = fileSR.ReadLine();
while (line != null)
{
hoursArray[counter] = int.Parse(line);
counter = counter + 1;
line = fileSR.ReadLine();
}
fileSR.Close();
int total = 0;
double average = 0;
for (int index = 0; index < hoursArray.Length; index++)
{
total = total + hoursArray[index];
}
average = (double)total / hoursArray.Length;
int high = hoursArray[0];
for (int index = 1; index < hoursArray.Length; index++)
{
if (hoursArray[index] > high)
{
high = hoursArray[index];
}
}
Console.WriteLine("Highest number is: " + high);
Console.WriteLine("The average is: " + average);
Console.ReadLine();
}
private void BasketBallStats_Load_1(object sender, EventArgs e)
{
}
private void CalcAverage_Click(object sender, EventArgs e)
{
int totalmarks = 0;
foreach (int m in Marks)
totalmarks += m;
MessageBox.Show("Average Is: " + totalmarks / Marks.Count);
}
private void Button1_Click(object sender, EventArgs e)
{
var c = new BasketballController("basketBallScore.txt");
Debug.WriteLine(string.Format("Average {0}", c.Average));
Debug.WriteLine(string.Format("First {0} {1}", c.Data.First().Name, c.Data.First().Value));
Debug.WriteLine(string.Format("Last {0} {1}", c.Data.Last().Name, c.Data.Last().Value));
}
}
}
程序将访问该文件,但在数据文件验证之外不会给出任何输出 尝试以下代码读取文件:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.txt";
static void Main(string[] args)
{
new Player(FILENAME);
}
}
public class Player
{
const int NAME_COL_WIDTH = 20;
public static List<Player> players = new List<Player>();
public string name { get; set; }
public int score { get; set; }
public Player() { } //player constructor with no parameters
public Player(string filename)
{
StreamReader reader = new StreamReader(filename);
string inputLine = "";
while((inputLine = reader.ReadLine()) != null)
{
Player newPlayer = new Player();
players.Add(newPlayer);
newPlayer.name = inputLine.Substring(0, NAME_COL_WIDTH).Trim();
newPlayer.score = int.Parse(inputLine.Substring(NAME_COL_WIDTH));
}
reader.Close();
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.txt”;
静态void Main(字符串[]参数)
{
新玩家(文件名);
}
}
公开课选手
{
常数int NAME\u COL\u WIDTH=20;
public static List players=new List();
公共字符串名称{get;set;}
公共整数分数{get;set;}
public Player(){}//不带参数的Player构造函数
公共播放器(字符串文件名)
{
StreamReader=新的StreamReader(文件名);
字符串inputLine=“”;
而((inputLine=reader.ReadLine())!=null)
{
Player newPlayer=新玩家();
players.Add(newPlayer);
newPlayer.name=inputLine.Substring(0,name\u COL\u WIDTH).Trim();
newPlayer.score=int.Parse(inputLine.Substring(NAME\u COL\u WIDTH));
}
reader.Close();
}
}
}
有几件事:
- 当您在代码中看到文件名两次(实际上是4次)时,您就会遇到一个等待发生的问题。用类成员替换所有这些文本
- 通常,在处理文本文件时,您不会将其保持打开状态,而是遵循以下模式:
- 以只读模式打开文件
- 读取数据
- 关闭文件
- 处理数据
- 以写模式打开文件
- 写入数据(覆盖上一个文件)
- 关闭文件 并在打开和关闭操作之间尽可能少地等待。不管你怎么做
private void Form1_Load(object seneder, EventArgs e)
{
try
{
filbasketBallStat = new StreamWriter("basketBallScore.txt");
如果您检查MSDN中的构造函数,您将阅读以下内容:
如果文件存在,则覆盖该文件;否则,将创建一个新文件
因此,当运行此程序时,您的文件应该是空白的,因此没有任何内容可读取,也没有任何内容可报告
您可能还应该将功能从表单中抽象出来。这将为您提供更大的灵活性,并允许您更轻松地进行调试
这应该起作用:
class BasketballController
{
public class Entry
{
public int Value { get; set; }
public string Name { get; set; }
}
BasketballController(string filename)
{
this.filename = filename;
}
private string filename;
private List<Entry> data = new List<Entry>();
public List<Entry> Data
{
get
{
// Clear data
data.Clear();
// Iterate through lines
foreach (string line in System.IO.File.ReadLines(filename))
{
// Split by space
List<string> parts = line.Trim().Split(' ').ToList();
if (parts.Count() < 2)
continue;
// Number is last space separated string
int number = int.Parse(parts.Last());
// Remove number
parts.RemoveAt(parts.Count() - 1);
// Name is any previous word joined by space
string name = string.Join(" ", parts).Trim();
// Add number and name to data
data.Add(new Entry() { Name = name, Value = number });
}
// Sort from greater value to smaller
data.Sort(Comparer<Entry>.Create(
(l, r) => r.Value.CompareTo(l.Value)));
return data;
}
set
{
using (var writer = new System.IO.StreamWriter(filename))
{
foreach (var entry in value)
{
writer.WriteLine(string.Format("{0} {1}", entry.Name, entry.Value));
}
}
data = value;
}
}
public double Average
{
get
{
// Read file if data is empty, otherwise reuse its value
var src = (data.Count() == 0) ? Data : data;
if (src.Count() == 0)
return 0.0;
// Return average
return src.Average(x => x.Value);
}
}
}
哪些产出:
Average 16
First Kyrie Irving 37
Last Draymond Green 2
你的问题具体是什么?我不知道代码做错了什么。它没有输出任何信息,那么如何让代码输出信息呢?如何让它提供正确的输出信息?为什么不能正确保存文件?欢迎使用任何指针。文件是否已创建?如果创建了它,它是否为空(即零长度)?文件是否已创建,但不包含您期望的内容?(如果是,它实际上包含什么?)?并在按钮的末尾分配debug.writeline语句。不,
debug.writeline
只是查看变量值的一种方式。有趣的是,您将BasketballController
实例分配给一个变量(例如c
),然后您可以使用c.Average
和c.Data.First()
访问平均值和“点数”最多的玩家。您可以随意使用,例如,与GUI逻辑集成,没有实际的表单很难遵循。我非常感谢您的澄清。但是我假设这个类应该在代码体中,然后我可以将debug.writeline语句集成到一个可能的BtnCalculate\u单击按钮中。忘记debug.writeline
,它在调试时很有帮助,看到这个类只是您添加到项目中的东西,你可以用任何你想用的方式。通过将其添加到自己的.cs
文件到项目中,或将其添加到您的.cs
文件中,该文件包含类外或类内的表单。你不能做的一件事就是把它放在一个方法中。那么我应该忽略那些语句吗?就这么写吧?WriteLine(string.Format(“Average{0}”,c.Average));WriteLine(string.Format(“First{0}{1}”,c.Data.First().Name,c.Data.First().Value));WriteLine(string.Format(“Last{0}{1}”、c.Data.Last().Name、c.Data.Last().Value));
var c = new BasketballController("basketBallScore.txt");
Debug.WriteLine(string.Format("Average {0}", c.Average));
Debug.WriteLine(string.Format("First {0} {1}", c.Data.First().Name, c.Data.First().Value));
Debug.WriteLine(string.Format("Last {0} {1}", c.Data.Last().Name, c.Data.Last().Value));
Average 16
First Kyrie Irving 37
Last Draymond Green 2