TheSwamp

Code Red => .NET => Topic started by: David Hall on February 06, 2008, 08:19:50 PM

Title: Read file, write file
Post by: David Hall on February 06, 2008, 08:19:50 PM
ok, I'm sure there is a MUCH better way to do this, but I'm trying to bang this out real fast.  Im opening a file, and parsing character by character and counting how many "A's", "B's", etc.  Eventually I will write this out to a file, but I'm interested if anyone has a better way to parse this information.
Code: [Select]
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Signage
{
    class Program
    {
        public static void Main(string[] args)
        {
            int intA = 0;
            int intB = 0;
            int intC = 0;
            int intD = 0;
            int intE = 0;
            int intF = 0;
            int intG = 0;
            int intH = 0;
            int iniI = 0;
            int intJ = 0;
            int intK = 0;
            int intL = 0;
            int intM = 0;
            int intN = 0;
            int intO = 0;
            int intP = 0;
            int intQ = 0;
            int intR = 0;
            int intS = 0;
            int intT = 0;
            int intu = 0;
            int intV = 0;
            int intW = 0;
            int intX = 0;
            int intY = 0;
            int intZ = 0;
            int int1 = 0;
            int int2 = 0;
            int int3 = 0;
            int int4 = 0;
            int int5 = 0;
            int int6 = 0;
            int int7 = 0;
            int int8 = 0;
            int int9 = 0;
            int int0 = 0;

            using (StreamReader sr = new StreamReader("c:/TestFile.txt"))
            {

                string currentChar;
                while ((currentChar = sr.Read().ToString()) != "-1")
                {
                    switch (currentChar)
                    {
                        case "65":
                            intA++;
                            break;
                        case "66":
                            intB++;
                            break;
                        case "67":
                            intC++;
                            break;
                        case "68":
                            intD++;
                            break;
                        case "69":
                            intE++;
                            break;
                        case "70":
                            intF++;
                            break;
                        case "71":
                            intG++;
                            break;
                        case "72":
                            intH++;
                            break;
                        case "73":
                            intI++;
                            break;
                        case "74":
                            intJ++;
                            break;
                        case "75":
                            intK++;
                            break;
                        case "76":
                            intL++;
                            break;
                        case "77":
                            intM++;
                            break;
                        case "78":
                            intN++;
                            break;
                        case "79":
                            intO++;
                            break;
                        case "80":
                            intP++;
                            break;
                        case "81":
                            intQ++;
                            break;
                        case "82":
                            intR++;
                            break;
                        case 83:
                        case 84:
                        case 85:
                        case 86:
                        case 87:
                        case 88:
                        case 89:
                        case 90:
                        case 91:
                        case 92:
                        case 93:
                        case 94:
                        case 95:
                        case 96:
                        case 97:
                        case 98:
                        case 99:
                        case 100:

                        default:
                            break;
                    }
                }

            }
            Console.WriteLine("A=" + intA.ToString());
            Console.WriteLine("B=" + intB.ToString());
        }
    }
}
Title: Re: Read file, write file
Post by: David Hall on February 06, 2008, 08:20:52 PM
As you can see from the code, I quit writing at about 82, looking to you guys for pointers.
Title: Re: Read file, write file
Post by: MickD on February 06, 2008, 08:34:40 PM
Perhaps you can use a map/dictionary (yes I like those :) ), create the 'keys' with the int values using a loop and store the 'A++' in the 'value' of the key.
As you read in the keys, add one to the value in a loop, something like (pseudo code) -

// creating the dictionary/map
Dict dict = new Dict();
// create the records:
For (i=0; i<36; i++) //amount of vals
    dict.addRecord(key = 65+i.asString() , value = 0);
end

// reading and storing:
while(not end of file)
 read in a char
    dict.getAt(asAsciiNum(char)) += 1;
end while
   
hth.

PS. I'd write an example for you David but it would take me longer to set up my c# ide and study the api than it would to code it :laugh:
Title: Re: Read file, write file
Post by: David Hall on February 06, 2008, 08:55:54 PM
OK, most of that went over my head, but I get the gist. :-)  I will look up Dict's tomorrow at work.
Title: Re: Read file, write file
Post by: David Hall on February 06, 2008, 08:56:24 PM
Other than that, do you think Im on track for parsing the file?
Title: Re: Read file, write file
Post by: MickD on February 06, 2008, 09:02:47 PM
I think the logic is there, a dictionary/map is just like a db, it has a key (like primary key if you like) which is the link to the stored data. In each loop you give the dictionary the key and it gives you access to the data.
To create the dict just use a loop and create a record for each char. The best part is if the key doesn't exist (say it's a space or comma etc.) you can just 'continue' the loop.

As far as the file read/write goes I haven't looked at C# for quite a while now so I'm no real help there I'm afraid.
Title: Re: Read file, write file
Post by: Kerry on February 06, 2008, 09:35:23 PM

David, sorry, I'm just flying past ..

perhaps Have a look an using LINQ ...

http://msdn2.microsoft.com/en-us/library/bb397940.aspx#Mtps_DropDownFilterText

OR regex may do the trick.
Title: Re: Read file, write file
Post by: MickD on February 06, 2008, 10:03:23 PM
I just remembered too, a hashtable may be easier and faster(??).
Just another option.
Title: Re: Read file, write file
Post by: SomeCallMeDave on February 06, 2008, 10:04:09 PM
Breaking codes?

You could use the Enumerator of a String to read each character.

I'm sure this isn't great C# coding, but it seems to work

Code: [Select]
using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace CharCount
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] counts = new int[91];
            using (StreamReader sr = new StreamReader("c:/testfile.txt"))
            {
                String fullFile = sr.ReadToEnd();
                String upper = fullFile.ToUpper();

                IEnumerator chars = upper.GetEnumerator();
                while (chars.MoveNext())
                {
                    char current = (char)chars.Current;
                    int currInt = Convert.ToInt16(current);
                    if (currInt >= 48 & currInt <= 90 )
                    {
                        counts[currInt]++;
                    }
                }
            }

            for (int i = 48; i < 58; i++)
            {
                Console.WriteLine("\nNumber of {0}'s is {1}", Convert.ToChar(i), counts[i]);
            }
            for (int i = 65; i < 91; i++)
            {
                Console.WriteLine("\nNumber of {0}'s is {1}", Convert.ToChar(i), counts[i]);
            }

            Console.WriteLine("\nHit enter to continue");
            Console.ReadLine();
        }
    }
}



Title: Re: Read file, write file
Post by: MickD on February 06, 2008, 10:10:03 PM
Nice one David! Simple too :)
Title: Re: Read file, write file
Post by: SomeCallMeDave on February 06, 2008, 10:13:00 PM
Thanks.  Simple is about all I can do in C# :-D

It can be expanded too,  to count other characters by playing with the array index and the test values in the for loops.
Title: Re: Read file, write file
Post by: MickD on February 06, 2008, 10:21:05 PM
Thanks.  Simple is about all I can do in C# :-D

It can be expanded too,  to count other characters by playing with the array index and the test values in the for loops.

Yep, with a little bit more math you could also reduce the size of the array, whether it's worth it or not though ...
Title: Re: Read file, write file
Post by: SomeCallMeDave on February 07, 2008, 08:50:29 AM
Using Regex .   Again, not pretty, but seems to work

Code: [Select]

using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace CharCount
{
    class Program
    {
        static int CountMe(String pChar, String pString)
        {
            Regex rx = new Regex("[" + pChar.ToLower() + pChar.ToUpper()+ "]");
            MatchCollection matches = rx.Matches(pString);
            return matches.Count;
        }

        static void Main(string[] args)
        {
            int[] counts = new int[91];
            int[] Testcounts = new int[91];

            using (StreamReader sr = new StreamReader("c:/testfile.txt"))
            {
                String fullFile = sr.ReadToEnd();
                String upper = fullFile.ToUpper();  // CountMe doesn't require this

                for (int i = 65; i < 91; i++)
                {
                    Testcounts[i]= CountMe(Convert.ToChar(i).ToString(), upper);  // there must be a cleaner way to do this

                }
            }


            for (int i = 65; i < 91; i++)
            {
                Console.WriteLine("\nNumber of {0}'s is {1}", Convert.ToChar(i), Testcounts[i]);
            }

            Console.WriteLine("\nHit enter to continue");
            Console.ReadLine();
        }
    }
}



Title: Re: Read file, write file
Post by: David Hall on February 07, 2008, 10:04:23 AM
I have 2 projects I have to get out today, but thanks a bunch everyone.  I definitly have some ideas to read up on now and move forward.  I'll keep you posted on how it goes.
Title: Re: Read file, write file
Post by: SomeCallMeDave on February 07, 2008, 01:29:47 PM
I'm a bit bored today so I've been having a play with this task.

Here is a simple version (no exception catching, etc)  with an extension method of the String object that uses LINQ to count the occurences

Code: [Select]

using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace CharCount
{
    public static class StringExtension
    {
        internal static int CountChar(this String pString, String pChar)
        {
            IEnumerable<char> query = from s in pString
                                      where s.ToString() == pChar
                                      select s;
            return query.Count();

        }

        internal static int CountChar(this String pString, char pChar)
        {
            IEnumerable<char> query = from s in pString
                                      where s.ToString() == pChar.ToString()
                                      select s;
            return query.Count();

        }
        internal static int CountChar(this String pString, int pIntValOfChar)
        {
            IEnumerable<char> query = from s in pString
                                      where s.ToString() == Convert.ToChar(pIntValOfChar).ToString()
                                      select s;
            return query.Count();

        }

    }//StringExtension

    class Program
    {
        static void Main(string[] args)
        {
            int[] Counts = new int[91];

            using (StreamReader sr = new StreamReader("c:/testfile.txt"))
            {
                String fullFile = sr.ReadToEnd();
                String upper = fullFile.ToUpper();

                //usage of extension method
                int k = upper.CountChar("A");
                int l = upper.CountChar('B');
                int m = upper.CountChar(67);

                for (char j = '0'; j <= '9'; j++)
                {
                    Counts[Convert.ToInt16(j)] = upper.CountChar(j);
                    Console.WriteLine("\nNumber of {0}'s is {1}", j.ToString(), Counts[Convert.ToInt16(j)]);
                }

                for (char j = 'A'; j <= 'Z'; j++)
                {
                    Counts[Convert.ToInt16(j)] = upper.CountChar(j);
                    Console.WriteLine("\nNumber of {0}'s is {1}", j.ToString(), Counts[Convert.ToInt16(j)]);
                }

                Console.WriteLine("\nHit enter to continue");
                Console.ReadLine();

            }

        }
}


C# sure is fun   :-D
Title: Re: Read file, write file
Post by: T.Willey on February 07, 2008, 03:21:10 PM
I'm such a noob I couldn't even get it to print to the command line.  Here is my donation.
Code: [Select]
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace WindosApps
{
/// <summary>
/// Description of ReadFile.
/// </summary>
public class ReadFile
{

[STAThread]
public static void Main()
{
string FullFile;
Dictionary<char, int> Dict = new Dictionary<char, int>();
using (StreamReader sr = new StreamReader("c:/test.txt")) {
FullFile = sr.ReadToEnd();
}
foreach (char chr in FullFile.ToCharArray()) {
if (Dict.ContainsKey(chr))
Dict[chr] = ++Dict[chr];
else
Dict.Add(chr, 1);
}
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<char, int> kvp in Dict) {
//Console.WriteLine("Letter {0} appears {1} time(s).", kvp.Key, kvp.Value);
sb.Append("\n");
sb.Append(kvp.Key.ToString());
sb.Append(" [ ");
sb.Append(kvp.Value.ToString());
sb.Append(" ]");
}
//Console.WriteLine("\n Hit enter to continue.");
//Console.ReadLine();
MessageBox.Show(sb.ToString());
}
}
}
Title: Re: Read file, write file
Post by: David Hall on February 07, 2008, 03:38:54 PM
I'm such a noob I couldn't even get it to print to the command line.  Here is my donation.
Autocad command line or console cmd line?
This is not inside autocad, and doesn't have the autocad references needed to print to cmd line there.

If you knew this, just ignore me
Title: Re: Read file, write file
Post by: T.Willey on February 07, 2008, 03:43:05 PM
I'm such a noob I couldn't even get it to print to the command line.  Here is my donation.
Autocad command line or console cmd line?
This is not inside autocad, and doesn't have the autocad references needed to print to cmd line there.

If you knew this, just ignore me
I was just doing it as a windows based program, so no Acad references.

Here is a better version.  It will only allow characters between 0-9, A-Z and a-z, and the dictionary, by definition, is sorted.
Code: [Select]
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace WindosApps
{
/// <summary>
/// Description of ReadFile.
/// </summary>
public class ReadFile
{

[STAThread]
public static void Main()
{
string FullFile;
//Dictionary<char, int> Dict = new Dictionary<char, int>();
SortedDictionary<char, int> Dict = new SortedDictionary<char, int>();
using (StreamReader sr = new StreamReader("c:/Raster2006.log")) {
FullFile = sr.ReadToEnd();
}
int tempInt;
foreach (char chr in FullFile.ToCharArray()) {
tempInt = (int)chr;
if
(tempInt < 91 && tempInt > 64
||
tempInt < 123 && tempInt > 96
||
tempInt < 58 && tempInt > 47
)
{
if (Dict.ContainsKey(chr))
Dict[chr] = ++Dict[chr];
else
Dict.Add(chr, 1);
}
}
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<char, int> kvp in Dict) {
//Console.WriteLine("Letter {0} appears {1} time(s).", kvp.Key, kvp.Value);
sb.Append("\n");
sb.Append(kvp.Key.ToString());
sb.Append(" [ ");
sb.Append(kvp.Value.ToString());
sb.Append(" ]");
}
//Console.WriteLine("\n Hit enter to continue.");
//Console.ReadLine();
MessageBox.Show(sb.ToString());
}
}
}
Title: Re: Read file, write file
Post by: David Hall on February 07, 2008, 04:02:43 PM
OK, I can see from the submissions, I definitly need t learn how to use Dict objects.
Title: Re: Read file, write file
Post by: David Hall on February 08, 2008, 12:32:51 PM
OK, thanks everybody for the input.  I have a working bit of code using the Console, now I would like to move to a windows form.  Let me say I have NEVER done a windows form in C# other than HelloWorld.  Im thinking this should be pretty straight forward, but I want to be able to pick a file from the form.  I'll keep you posted on my progress.
Title: Re: Read file, write file
Post by: David Hall on February 08, 2008, 12:33:19 PM
For those playing along, here is my code so far
Code: [Select]
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Signage
{
    class Program
    {
        public static void Main(string[] args)
        {
            string FullFile;
            string flInput;
            string flOutput;
            Console.WriteLine("Enter File Name to process with a / slash");
            flInput = Console.ReadLine();
            Console.WriteLine("Enter File Name to Output to with a / slash");
            flOutput = Console.ReadLine();
            StreamWriter sw = new StreamWriter(flOutput);
            SortedDictionary<char, int> Dict = new SortedDictionary<char, int>();
            using (StreamReader sr = new StreamReader(flInput))
            {
                FullFile = sr.ReadToEnd();
            }
            int tempInt;
            foreach (char chr in FullFile.ToCharArray())
            {
                tempInt = (int)chr;
                if
                    (tempInt < 91 && tempInt > 64
                     ||
                     tempInt < 123 && tempInt > 96
                     ||
                     tempInt < 58 && tempInt > 31 //47  Changed to pick up the ()'. and space characters
                    )
                {
                    if (Dict.ContainsKey(chr))
                        Dict[chr] = ++Dict[chr];
                    else
                        Dict.Add(chr, 1);
                }
            }

            foreach (KeyValuePair<char, int> kvp in Dict)
            {
                StringBuilder sb = new StringBuilder();
                //sb.Append("\n");   Removed b/c it was not needed using WriteLine and it was creating unknown char in txt file
                sb.Append("Character: ");
                sb.Append(kvp.Key.ToString());
                sb.Append(" - [ ");
                sb.Append(kvp.Value.ToString());
                sb.Append(" ]");
                sw.WriteLine(sb);
                sw.Flush();
            }
            sw.Close();
        }
    }
}
Title: Re: Read file, write file
Post by: David Hall on February 08, 2008, 02:04:16 PM
Here is the windows form version
Code: [Select]
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SubStationSignage
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnFileToProcess_Click(object sender, EventArgs e)
        {
            openFileDialog1.InitialDirectory = "c:\\";
            openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 0;
            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.FileName = string.Empty;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                txtFileToProcess.Text  = openFileDialog1.FileName;
            }
        }

        private void btnFileToCreate_Click(object sender, EventArgs e)
        {
            saveFileDialog1.InitialDirectory = "c:\\";
            saveFileDialog1.FileName = string.Empty;
            saveFileDialog1.DefaultExt = "txt";
            saveFileDialog1.Filter = "txt files (*.txt)|*.txt";

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                txtFileToCreate.Text = saveFileDialog1.FileName;
            }
        }

        private void btnBegin_Click(object sender, EventArgs e)
        {
            if ((txtFileToProcess.Text != string.Empty) && (System.IO.File.Exists(txtFileToProcess.Text)) && (txtFileToCreate.Text != string.Empty))
            {
                if (System.IO.File.Exists(txtFileToCreate.Text))
                {
                    System.IO.File.Delete(txtFileToCreate.Text);
                }
                string FullFile;
                string flInput = txtFileToProcess.Text;
                string flOutput = txtFileToCreate.Text;
                StreamWriter sw = new StreamWriter(flOutput);
                SortedDictionary<char, int> Dict = new SortedDictionary<char, int>();
                using (StreamReader sr = new StreamReader(flInput))
                {
                    FullFile = sr.ReadToEnd();
                }
                int tempInt;
                foreach (char chr in FullFile.ToCharArray())
                {
                    tempInt = (int)chr;
                    if
                        (tempInt < 91 && tempInt > 64
                         ||
                         tempInt < 123 && tempInt > 96
                         ||
                         tempInt < 58 && tempInt > 31 //47
                        )
                    {
                        if (Dict.ContainsKey(chr))
                            Dict[chr] = ++Dict[chr];
                        else
                            Dict.Add(chr, 1);
                    }
                }

                foreach (KeyValuePair<char, int> kvp in Dict)
                {
                    StringBuilder sb = new StringBuilder();
                    //sb.Append("\n");
                    sb.Append("Character: ");
                    sb.Append(kvp.Key.ToString());
                    sb.Append(" - [ ");
                    sb.Append(kvp.Value.ToString());
                    sb.Append(" ]");
                    sw.WriteLine(sb);
                    sw.Flush();
                }
                sw.Close();
            }
        }
    }
}
Title: Re: Read file, write file
Post by: David Hall on February 08, 2008, 02:06:25 PM
Next question, I see that the Dictionary has key/value pairs.  What I need is triplets.   Is this possible?  Where key would be the Character ie "A", Value would be Character.Count - 3, and the 3rd value would be our Stores Number (part number in warehouse) ie 5121802
Title: Re: Read file, write file
Post by: T.Willey on February 08, 2008, 02:21:54 PM
Next question, I see that the Dictionary has key/value pairs.  What I need is triplets.   Is this possible?  Where key would be the Character ie "A", Value would be Character.Count - 3, and the 3rd value would be our Stores Number (part number in warehouse) ie 5121802
I don't think so, but you maybe be able to do it.  You could define the key as a List or ArrayList, and then just add one to the first (or second) value in the List, but that is just thinking out loud.
Title: Re: Read file, write file
Post by: David Hall on February 08, 2008, 04:04:56 PM
I have another question that is perplexing me.  I wrote this using .Net3.5, and it works on a machine w/ .Net3.0.  Is this b/c my project is so simple the form stuff hasn't changed in 3.5?  Also, using Express, how can I make a deployable exe for distribution?
Title: Re: Read file, write file
Post by: Chuck Gabriel on February 08, 2008, 04:23:59 PM
Next question, I see that the Dictionary has key/value pairs.  What I need is triplets.   Is this possible?  Where key would be the Character ie "A", Value would be Character.Count - 3, and the 3rd value would be our Stores Number (part number in warehouse) ie 5121802

Could you declare your container something like this:

Dictionary<char, KeyValuePair<int, int> > mrDuhsContainer = new Dictionary<char, KeyValuePair<int, int> >;
Title: Re: Read file, write file
Post by: T.Willey on February 08, 2008, 05:02:48 PM
I have another question that is perplexing me.  I wrote this using .Net3.5, and it works on a machine w/ .Net3.0.  Is this b/c my project is so simple the form stuff hasn't changed in 3.5?
Yes.

Also, using Express, how can I make a deployable exe for distribution?
Don't know since I use SharpDevelop, and I only code for myself really.
Title: Re: Read file, write file
Post by: David Hall on February 08, 2008, 05:30:07 PM
Next question, I see that the Dictionary has key/value pairs.  What I need is triplets.   Is this possible?  Where key would be the Character ie "A", Value would be Character.Count - 3, and the 3rd value would be our Stores Number (part number in warehouse) ie 5121802

Could you declare your container something like this:

Dictionary<char, KeyValuePair<int, int> > mrDuhsContainer = new Dictionary<char, KeyValuePair<int, int> >;
Sounds good to me, will have try that on monday
Title: Re: Read file, write file
Post by: David Hall on February 08, 2008, 05:30:32 PM
I have another question that is perplexing me.  I wrote this using .Net3.5, and it works on a machine w/ .Net3.0.  Is this b/c my project is so simple the form stuff hasn't changed in 3.5?
Yes.

thought so
Title: Re: Read file, write file
Post by: Kerry on February 08, 2008, 07:43:50 PM
David,
I'd handle the initialisation of the Dictionary slightly differently ; with a mind to making modifications more efficient without needing to recompile the code.

If you were to have a definition file that contained {say} one entry per item for ;

char , catalogCode

ie
a 101234583
~ 102333356
etc ..

read this file in and initialise the Dictionary , adding a zero count for each.

you could then replace the casting of chars and the testing of the resultant int value
with a simple 
                        if (Dict.ContainsKey(chr))
                            Dict[chr] = ++Dict[chr];  //<<==== or whatever :-)

being secure in the knowledge that ONLY the characters you want to count will be already in the Dictionary.
 
Title: Re: Read file, write file
Post by: David Hall on February 09, 2008, 10:35:19 AM
Thanks Kerry.  I was thinking that, but hadn't figured out how I wanted to deal with it yet.  Are you saying that "a 10123
4583" would be ghe first value in the Dict, and the Count would be the second value?  I can see how that would work.  Ill have a go at it in a few minutes
Title: Re: Read file, write file
Post by: Kerry on February 09, 2008, 06:36:26 PM

Hi David,
I actually meant to use the first element as the key and the remaining elements as a List for the value.
.... but .. I've had second thoughts, cause the efficiency will depend on the quantum of hits the Dictionary is taking to update the value ( ie: how big is your text file ) and on what you will do with the data when it's collected.

.. though I still think initialising the dictionary from an external source is preferable.

It may be better to just collect the data in the simple dictionary then do the collation with the catalog numbers as a separate process.
Title: Re: Read file, write file
Post by: David Hall on February 09, 2008, 08:03:13 PM
It may be better to just collect the data in the simple dictionary then do the collation with the catalog numbers as a separate process.
I was thinking this, as my list of characters is very small, 40 at most (alpha, numeric, ().-).  Maybe the ' if needed, but still, very small list.  And, per substation, there will be a very few high quanity letters, and others that have a small quanity.  Most characters wont have any at all.
Title: Re: Read file, write file
Post by: Chuck Gabriel on February 09, 2008, 10:05:06 PM
40 characters?  You're gonna need a bigger alphabet. :-)
Title: Re: Read file, write file
Post by: Glenn R on February 10, 2008, 05:52:23 AM
Code: [Select]
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace CountChars {

class Program {

static void Main(string[] args) {

string fullFile = null;

using (TextReader tr = File.OpenText(@"C:\Temp\CountCharsTest.txt"))
fullFile = tr.ReadToEnd();

SortedDictionary<char, int> charDict = new SortedDictionary<char, int>();

foreach (char c in fullFile) {
if (!char.IsLetter(c))
continue;
if (charDict.ContainsKey(c))
charDict[c]++;
else
charDict.Add(c, 1);
}

foreach (KeyValuePair<char, int> kvp in charDict)
Console.WriteLine("Character: {0}\tCount: {1}", kvp.Key, kvp.Value);

Console.ReadLine();
}
}
}
Title: Re: Read file, write file
Post by: David Hall on February 10, 2008, 05:36:12 PM
40 characters?  You're gonna need a bigger alphabet. :-)
We only use Capital letters in our signs, so I was thinking 26 letters, 10 numbers and a few punctionation marks would give me about 40 characters.
Title: Re: Read file, write file
Post by: David Hall on February 10, 2008, 05:38:54 PM
Glenn, I see you used a TextReader instead of a Streamreader.  Can I ask why and what benefits one has over the other?
Title: Re: Read file, write file
Post by: Chuck Gabriel on February 10, 2008, 05:44:25 PM
40 characters?  You're gonna need a bigger alphabet. :-)
We only use Capital letters in our signs, so I was thinking 26 letters, 10 numbers and a few punctionation marks would give me about 40 characters.

I figured it was something like that, but I couldn't stop myself from trying to be witty.  :-)
Title: Re: Read file, write file
Post by: MP on February 11, 2008, 12:48:12 AM
Last think I should embark on whilest under the influence of a sleeping pill is something like this, never mind sober, but I couldn't stop myself.

It's been a long time since I did any C# so I said "Time to re-hone those atrophying skills", ergo an attempt here.

I went the easy way of buffered binary read, thinking it would be faster (since we're ultimately dealing with binary data why convert to and from), and more bomb proof on large files.

Processes a 50 MB file pretty fast, maybe 1 second?

Anyway, sewerage --

Code: [Select]
using System;
using System.IO;

namespace Thetan
{
    class Program
    {
        private const int BUFFER_SIZE = 8192;

        private static long[] IndexBytes( string filename )
        {
            //  caller's responsibility to
            //  pass a valid, readable file
           
            long[] result = new long[ 256 ];

            //  use buffered binary read. Should be fast
            //  and won't chuck a wobbly on big files

            Stream inputStream            = File.OpenRead( filename );
            BufferedStream bufferedStream = new BufferedStream( inputStream );
            byte[] buffer                 = new byte[ BUFFER_SIZE ];
            int bytesRead;

            while ( ( bytesRead = bufferedStream.Read( buffer, 0, BUFFER_SIZE )) > 0 )
                for ( int i = 0 ; i < bytesRead ; i++ )
                    result[ buffer[ i ] ]++;
           
            bufferedStream.Close();

            return result;

        } //------------------------------------------------------------

        static void Main(string[] args)
        {
            //  This file example file is about 53 MB.
           
            string filename = @"C:\Docs\Downloads\iTunesSetup.exe";
           
            if ( File.Exists( filename ) )
            {
                long[] results = IndexBytes( filename);               
                ShowResults ( results, false );
            }

        } //------------------------------------------------------------
       
        private static void ShowResults ( long[] results, bool toUpper )
        {
            if ( toUpper ) // force upper case registers
                           // to represent lower + upper
            {   
                for ( int i = 65, k = 97 ; i < 91 ; i++, k++ )
                {   
                    results[i] += results[k];
                    results[k]  = 0;
                }   
            }         
           
            Console.WriteLine( "Talley" );           
            Console.WriteLine( "=============" );
           
            ShowRange ( results, 48, 58 );
            if ( !toUpper ) ShowRange ( results, 97, 123 );
            ShowRange ( results, 65, 91 );
           
            Console.WriteLine( "\nPress [Enter] to continue" );
            Console.ReadLine();
           
        } //------------------------------------------------------------

        private static void ShowRange ( long[] results, int startIndex, int endIndex )
        {
            for ( int i = startIndex ; i < endIndex ; i++ )
            {
                Console.WriteLine( "{0}'s => {1}", (char)i, results[i] );
            }
        }
    }
}

Looks verbose but I'm guessing it performs well against the other versions (tho I never benched anything myself).