I'm a newer programmer with C#. I am having an issue where my character frequency reading program is not displaying the ASCII values correctly. What it is supposed to do is read from a text file, convert all uppercase to lowercase, display the ASCII values, frequency appeared, and percentage of the total number of characters each character appears in the file and then sort the list by frequency. Below is my code so far:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.IO;
using LibUtil;
using LibDate;
namespace Ch8Prb3
{
class Program
{
const string INPUT_FILE_NAME = "\\CIS210\\Ch8Prb3\\TextDat.Txt";
const string OUTPUT_FILE_NAME = "\\CIS210\\Ch8Prb3\\Ch8Prb3Rpt.Txt";
int count;
static StreamReader fileIn;
static StreamWriter fileOut;
static void Main()
{
ConsoleApp.ClrScr(); IdentifyApplication();
OpenFiles(); LetterFreq();
CloseFiles();
}
static void IdentifyApplication()
{
Console.WriteLine();
Console.WriteLine("Application: Ch8Prb3 -- Find and display a character-frequency ");
Console.WriteLine(" report of only letter chracters and their");
Console.WriteLine(" ASCII values from a text file.");
Console.WriteLine();
}
static void OpenFiles()
{
try
{
fileIn = File.OpenText(INPUT_FILE_NAME);
Console.WriteLine("{0} was opened", INPUT_FILE_NAME);
}
catch
{
Console.WriteLine("Error: {0} does not exist\n", INPUT_FILE_NAME);
ConsoleApp.Exit();
}
try
{
fileOut = File.CreateText(OUTPUT_FILE_NAME);
Console.WriteLine("{0} was created\n", OUTPUT_FILE_NAME);
}
catch
{
Console.WriteLine("Error: {0} could not be created\n", OUTPUT_FILE_NAME);
ConsoleApp.Exit();
}
}
static void LetterFreq()
{
int[] c = new int[(int)char.MaxValue];
int total = 0;
int j = 0;
string s = File.ReadAllText("\\CIS210\\Ch8Prb3\\TextDat.Txt");
string l = Convert.ToString(Encoding.ASCII.GetBytes(s));
s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToLower(s.ToLower());
double percent;
foreach (char t in s)
{
c[(int)t]++;
}
PrintHeader();
for (int i = 0; i < (int)char.MaxValue; i++)
{
if (c[i] > 0 && char.IsLetter((char)i))
{
total += c[i];
percent = c[i] / total * 100;
fileOut.WriteLine(" {0} {1,3} {2,3} {3,2:f2}", (char)i, l, c[i], percent);
}
}
fileOut.WriteLine();
fileOut.WriteLine("Number of Characters: {0}", total);
}
static void PrintHeader()
{
fileOut.WriteLine(" Chapter 8 Problem 3");
fileOut.WriteLine("Character Frequency Report");
fileOut.WriteLine(" {0:MM/dd/yyyy}", Date.Today);
fileOut.WriteLine();
fileOut.WriteLine(" ASCII ");
fileOut.WriteLine("Char Value Freq Percent");
fileOut.WriteLine("---- ----- ---- -------");
}
static void CloseFiles()
{
fileIn.Close(); fileOut.Close();
}
}
}
Instead of getting the ASCII value of each character, I'm getting System.Byte [] all the way down the ASCII column.
Help!
This is the problem:
Convert.ToString(Encoding.ASCII.GetBytes(s));
Encoding.GetBytes(string)
returns a byte[]
, and calling Convert.ToString()
on that will just return System.Byte[]
.
It's not clear why you're using Encoding.ASCII
at all here - you've got the contents of the file as a string, on the previous line:
string s = File.ReadAllText("\\CIS210\\Ch8Prb3\\TextDat.Txt");
Just use that instead of l
. It's not clear what you're expecting to do with l
anyway, to be honest. By "ASCII value" if you mean the Unicode code point for the character, just cast i
to int
:
fileOut.WriteLine(" {0} {1,3} {2,3} {3,2:f2}", (char)i, (int) i, c[i], percent);
Oh, and you probably want to change the way you're computing percent
, too - you're using integer arithmetic, so the result will always be 0.
It's not clear why you're lower-casing the string twice either, by the way. Don't you think once is enough? Why are you lower-casing at all?
Oh, and you open an input file, but never do anything with it. Why?
There are various other things I'd change about your code - not least the layout (one statement per line, almost always!) - but this'll do for a start.
See more on this question at Stackoverflow