user1548100
user1548100

Reputation: 25

how to read text file and count the same names

I wanna create text file containing one name on each line. Compute the number of times any name occurs. Output one line for each name in file and on each line print the number of occurrences followed by name.

I can open the file by using this code

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);
        }
    }
}

But what I want is to use the same button to read and display it in groupbox.

Upvotes: 0

Views: 3116

Answers (5)

Sayid
Sayid

Reputation: 1103

Similar question has been asked before: A method to count occurrences in a list

In my opinion using LINQ query is a good option.

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);
}

Upvotes: 0

Jodrell
Jodrell

Reputation: 35716

Okay, a function like this will build you distinct names with counts.

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(); 
        }
    }
}

Or you could do somthing flash with linq and 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);
}

The first option does have the adavantage of not loading the whole file into memory.

As for outputting the information,

var output = new StringBuilder();
foreach (valuePair in ParseNameFile(openFileDialog1.FileName))
{
    output.AppendFormat("{0} {1}\n", valuePair.Key, valuePair.Value); 
}

Then you ToString() on output to put the data anywhere you want. If there will very many rows, a StreamWriter approach would be preferred.

Upvotes: 0

SidAhmed
SidAhmed

Reputation: 2362

You can do that using Linq, without having to increment a int variable. To finaly have a dictionary containing names and counts

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);
}

Upvotes: 0

Ria
Ria

Reputation: 10347

(assuming this is a homework) I used File.ReadAllLine and 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);
}

Upvotes: 1

Polyfun
Polyfun

Reputation: 9639

As this is homework, I am not going to give you code, but hopefully enough info to point you in the right direction.

I suggest you use File.ReadAllLines to read the file into an array of strings, each item in the array is one line in the file. This means you do not have to split the file contents up yourself. Then you can loop over the string array, and add each line to a Dictionary, where the key is the line read from the file, and the value is the number of occurrences. You need to check whether the key is already in the Dictionary - if not add it with a count of 1, otherwise update the existing count (+1). After that loop, have a second loop which loops over the Dictionary contents, updating your textbox with the names and their counts.

Upvotes: 3

Related Questions