我想创建每行包含一个名称的文本文件。计算任何名称出现的次数。为文件中的每个名称输出一行,并在每行上输出出现次数,后跟名称。
我可以使用此代码打开文件
private void button1_Click(object sender, EventArgs e)
{
using (OpenFileDialog dlgOpen = new OpenFileDialog())
{
try
{
// Available file extensions
openFileDialog1.Filter = "All files(*.*)|*.*";
// Initial directory
openFileDialog1.InitialDirectory = "D:";
// OpenFileDialog title
openFileDialog1.Title = "Open";
// Show OpenFileDialog box
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
// Create new StreamReader
StreamReader sr = new StreamReader(openFileDialog1.FileName, Encoding.Default);
// Get all text from the file
string str = sr.ReadToEnd();
// Close the StreamReader
sr.Close();
// Show the text in the rich textbox rtbMain
}
}
catch (Exception errorMsg)
{
MessageBox.Show(errorMsg.Message);
}
}
}
但我想要的是使用相同的按钮来阅读并在组框中显示它。
答案 0 :(得分:3)
由于这是作业,我不打算给你代码,但希望有足够的信息指出你正确的方向。
我建议你使用File.ReadAllLines将文件读入一个字符串数组,数组中的每个项目都是文件中的一行。这意味着您不必自己拆分文件内容。然后,您可以循环遍历字符串数组,并将每行添加到Dictionary中,其中键是从文件读取的行,值是出现次数。您需要检查密钥是否已经在字典中 - 如果不是添加计数为1,否则更新现有计数(+1)。在该循环之后,使用第二个循环遍历Dictionary内容,使用名称及其计数更新文本框。
答案 1 :(得分:1)
(假设这是一个家庭作业)我使用了File.ReadAllLine
和Dictionary<TKey, TValue>
:
var nameCount = new Dictionary<string, int>();
foreach (String s in File.ReadAllLines("filename"))
{
if (nameCount.ContainsKey(s))
{
nameCount[s] = nameCount[s] + 1;
}
else
{
nameCount.Add(s, 1);
}
}
// and printing
foreach (var pair in nameCount)
{
Console.WriteLine("{0} count:{1}", pair.Key, pair.Value);
}
答案 2 :(得分:0)
以前曾提出过类似的问题: A method to count occurrences in a list
在我看来,使用LINQ查询是一个不错的选择。
string[] file = File.ReadAllLines(openFileDialog1.FileName, Encoding.Default);
IEnumerable<string> groupQuery =
from name in file
group name by name into g
orderby g.Key
select g;
foreach (var g in groupQuery)
{
MessageBox.Show(g.Count() + " " + g.Key);
}
答案 3 :(得分:0)
好的,像这样的函数会为你建立不同的名字。
private static IDictionary<string, int> ParseNameFile(string filename)
{
var names = new Dictionary<string, int>();
using (var reader = new StreamReader(filename))
{
var line = reader.ReadLine();
while (line != null)
{
if (names.ContainsKey(line))
{
names[line]++;
}
else
{
names.Add(line, 1);
}
line = reader.ReadLine();
}
}
}
或者你可以用linq和readAllLines做一些闪光。
private static IDictionary<string, int> ParseNameFile(string filename)
{
return File.ReadAllLines(filename)
.OrderBy(n => n)
.GroupBy(n => n)
.ToDictionary(g => g.Key, g => g.Count);
}
第一个选项确实具有不将整个文件加载到内存中的优点。
至于输出信息,
var output = new StringBuilder();
foreach (valuePair in ParseNameFile(openFileDialog1.FileName))
{
output.AppendFormat("{0} {1}\n", valuePair.Key, valuePair.Value);
}
然后您在输出上ToString()
将数据放入任何您想要的位置。如果行数非常多,则首选StreamWriter
方法。
答案 4 :(得分:0)
您可以使用Linq执行此操作,而无需增加int
变量。最终有一个包含姓名和计数的字典
string names = sr.ReadAllLines();
Dictionary<string, int> namesAndCount = new Dictionary<string, int>();
foreach(var name in names)
{
if(namesAndCount.ContainsKey(name))
continue;
var count = (from n in names
where n == name
select n).Count();
namesAndCount.Add(name, count);
}