How do I populate a listbox from a binary file in C#.net?

I am very new to programming, so this may be a basic question.  I am working in C#.net.  I have a binary file consisting of multiple records, each one formatted like so:

Last name, First name     Total points     Percent

I need to populate a listbox by reading this file and returning an arraylist with the data, but when I try it comes up oddly formatted, with numbers that don't exist in the file (there are no total points over 400, no percent over 100).  I need each line in the file to be displayed on its own line in the listbox, as I need to be able to select one line to add to an existing database table with the same fields (last name, first name, total, percent).

Also, the binary file was originally created with last name and first name separated by just a comma.  In this program they are two separate fields and I'm not sure how to do that.  If I just do the ReadString it reads it all as one.

Here is the code I have:

public ArrayList ReadBin(String filename)
        {            
            ArrayList cgList = new ArrayList();
            BinaryReader binfile = null;
            CourseGradesData cg1;
            try
            {
                binfile = new BinaryReader(
                    new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Read));

                while (binfile.PeekChar() != -1)
                {
                    cg1 = new CourseGradesData();
                    cg1.Lname = binfile.ReadString();
                    cg1.Fname = binfile.ReadString();                  
                    cg1.Total = (binfile.ReadInt32());
                    cg1.Percent = binfile.ReadDecimal();
                    cgList.Add(cg1);
                }
                binfile.Close();
            }
            catch (System.IO.IOException exc)
            {
                Console.WriteLine(" Error in processing file"
                    + exc.Message);
            }                      
            return cgList;
        }


I have attached the binary file I'm trying to read.  Any help would be much appreciated.
out.txt
Pettitte96Asked:
Who is Participating?
 
RyanAndresConnect With a Mentor Commented:
This goes beyond the original question.

You could make this static:
public ArrayList ReadBin(String filename)

And replace this line:
lstArray = cgd.ReadBin(ofdStudents.FileName);
with:
lstArray = CourseGradesData.ReadBin(ofdStudents.FileName);

You might also want to initialize cg1
0
 
RyanAndresCommented:
Do you have the documentation on how this file is outputted? It is more than just:

Last name, First name     Total points     Percent
0
 
Pettitte96Author Commented:
It was created in a console application in C#.  The application prompted for first name, then last name, then points.  It then calculated the percentage.  The code:

static void Main(string[] args)
        {
            CourseGrade [] cg = new CourseGrade[10];
            string strread;
            int grade;
            int arrayct = 0;
            float total;            
            char again;

            do
            {
                cg[arrayct] = new CourseGrade();
                Console.WriteLine(" Enter student's first name: ");
                cg[arrayct].Fname = Console.ReadLine();
                Console.WriteLine(" Enter student's last name: ");
                cg[arrayct].Lname = Console.ReadLine();
               
                total = 0;

                for (int ct = 0; ct < 4; ct++ )
                {                    
                    Console.WriteLine(" Enter grade");
                    strread = Console.ReadLine();
                    grade = Convert.ToInt16(strread);
                    cg[arrayct].Totalgrade += grade;                    
                }

                cg[arrayct].CalcPercent();

                Console.WriteLine(" Student Name: " + cg[arrayct].Fname + " " + cg[arrayct].Lname + "\n"
                    + " Total Grade: {0}", cg[arrayct].Totalgrade + "\n" + " Percent: "
                    + cg[arrayct].Finalpercent + "\n");

                arrayct++;

                Console.WriteLine(" Do you have any more students to enter? (y/n)");
                again = Convert.ToChar(Console.ReadLine());

            } while (again != 'N' && again != 'n');

            Console.Clear();
            outFilebin(cg, arrayct);
        }

        public static void outFilebin(CourseGrade [] cgrpt, int ct)
        {
            Console.WriteLine("\n Write to Binary file");
            BinaryWriter binfile = null;
            try
            {
                binfile = new BinaryWriter(
                    new FileStream("C:\\Projects\\out.dat", FileMode.OpenOrCreate,
                        FileAccess.Write));
            }
            catch (System.IO.IOException iox)
            {
                Console.WriteLine("Error in Open" + iox.Message);
            }
            for (int x = 0; x < ct; x++)
            {
                binfile.Write(cgrpt[x].Lname + ", " + cgrpt[x].Fname);
                binfile.Write(cgrpt[x].Totalgrade);
                binfile.Write(cgrpt[x].Finalpercent);
            }
            try
            {
                binfile.Close();
            }
            catch (System.IO.IOException iox)
            {
                Console.WriteLine("Error in Close" + iox.Message);
            }
        }
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
RyanAndresCommented:
Could you also provide the expected values for total grade and final percent for a couple of the following lines:

Lucas, Kathy...C...B  
Brown, Michael...C...B
Richards, John...C...B
Edwards, Kim...C...B  
Garvey, Lynn...C...B  
Finley, Steve...C...B  
Grossman, Terri...C...B
Grey, Ed...C...B      
0
 
Pettitte96Author Commented:
Name                       Total        Pct
------                         -------      -----
Lucas, Kathy         343          85.75
Brown, Michael        333          83.25
Richards, John          335          83.75
Edwards, Kim          305          76.25
Garvey, Lynn           368          92
Finley, Steve            354          88.5
Grossman, Terri            325          81.25
Grey, Ed                  322          80.5
0
 
RyanAndresCommented:
Your out.txt file does not match my out.dat file.

I have written a reader which works with your output code and ran on my machine, but it doesnt work with your attached out.txt.

Did you alter the out.txt file in any way? Ie, opened the original .dat file and saved it as a .txt file? I need the original file intact.
0
 
Pettitte96Author Commented:
I renamed it as a .txt, but did not actually open it and Save As.
0
 
RyanAndresCommented:
What kind of processor are you running the application on? This may affect the binary output's endian-ness.
0
 
Pettitte96Author Commented:
Intel Pentium 4
0
 
RyanAndresCommented:
I replicated the line for Kathy and got different format results in the .dat file.

Yours:
HEX: 0c      4c 75 63 61 73 2c 20 4b 61 74 68 79      00 80 ab 43      00 80 ab 42
ASCII: .Lucas, Kathy...C...B

Mine:
HEX: 0c      4c 75 63 61 73 2c 20 4b 61 74 68 79      57 01 00 00      02      38 35
ASCII: .Lucas, KathyW....8

As you can see, the total grade and percent is stored in mine properly.
Total grade = 57 01 00 00, reverse it, it becomes 00 00 01 57
157 is hex for 343 Binary

Percentage:
02 38 35 means there are 02 characters, 0x38 and 0x35.
0x38 = '8', 0x35 = '5'.

Note: This percent doesnt match yours because I calculated using an assumed formula.

So, I have broken down the binary file's format and written code to parse it. However, this is only valid if I ran your output program on my pc.

If you like, you could run it again and attach the .dat file. Make sure it's compiled in 32 bit.
0
 
Pettitte96Author Commented:
I re-ran the console application and re-created the .dat file.  I am not able to attach as it tells me that .dat is not an acceptable extension.  It won't let me attach it even if I zip it up.  This is why I re-named it originally.

I just re-named the new file to .txt, but I have not opened it or saved it.  The original file name is out.dat
out.txt
0
 
RyanAndresCommented:
Could you paste the code for the CourseGrade class since it's property values are used for the binary output.
0
 
Pettitte96Author Commented:
class CourseGrade
    {
        private string fname, lname;
        private float totalgrade;
        private float finalpercent;

        public CourseGrade()
        {
        }

        public string Fname
        {
            get
            {
                return fname;
            }
            set
            {
                fname = value;
            }
        }

        public string Lname
        {
            get
            {
                return lname;
            }
            set
            {
                lname = value;
            }
        }

        public float Totalgrade
        {
            get
            {
                return totalgrade;
            }
            set
            {
                totalgrade = value;
            }
        }

        public float Finalpercent
        {
            get
            {
                return finalpercent;
            }
            set
            {
                finalpercent = value;
            }
        }

        public float CalcPercent()
        {            
            finalpercent = ((totalgrade/400) * 100);        
            return finalpercent;
        }
    }
0
 
RyanAndresCommented:
bingo you're using floats!

give me a few minutes im multitasking with some other stuff.
0
 
RyanAndresCommented:
I should've asked for the datatypes in the first place, I thought they were int/double.

Here is the format of the binary data for your reference:

LINE FORMAT
BYTES      | TYPE      | DESCRIPTION
1      | int      | Length of Name
V      | str      | Lastname, Firstname
4      | float      | Total Points Value
4      | float      | Percent Value
FileStream stream = new FileStream("out.txt", FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(stream);
 
while(reader.PeekChar() != -1)
{
    int nameLength = reader.ReadByte();
 
    byte[] nameBytes = reader.ReadBytes(nameLength);
    string name = Encoding.ASCII.GetString(nameBytes);
 
    byte[] totalGradeBytes = reader.ReadBytes(4);
    double totalGrade = BitConverter.ToSingle(totalGradeBytes, 0);
 
    byte[] percentBytes = reader.ReadBytes(4);
    double percent = BitConverter.ToSingle(percentBytes, 0);
 
    Console.WriteLine(name + "\t" + totalGrade + "\t" + percent);
}

Open in new window

0
 
Pettitte96Author Commented:
When I put this code in I get nothing in my listbox after selecting the file.   I have an open file dialog allowing me to select the out.dat file, at which point the contents need to be displayed in a listbox on screen, in columns like so:

Kathy     Lucas          343          85.75
Michael  Brown         333          83.25
John      Richards      335          83.75
Kim        Edwards      305          76.25
Lynn      Garvey        368          92
Steve     Finley           354          88.5
Terri       Grossman    325          81.25
Ed           Grey            322          80.5
0
 
RyanAndresCommented:
I'm so sorry I did not include that as I was concentrating on the bigger task (reading the binary data).

You can easily add the data to the list box using the name, totalGrade, and percent variables.

For example:

string line = String.Format("{0} {1} {2}", name, totalGrade, percent);
listbox.Items.Add(line);

Please let me know if this is sufficient information.
0
 
RyanAndresCommented:
The following code includes the separation of the first and last names. You can then format the variables any way you like.
const string FilePath = "out.txt";
 
FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(stream);
 
while(reader.PeekChar() != -1)
{
    int nameLength = reader.ReadByte();
 
    byte[] nameBytes = reader.ReadBytes(nameLength);
    string name = Encoding.ASCII.GetString(nameBytes);
 
    byte[] totalGradeBytes = reader.ReadBytes(4);
    double totalGrade = BitConverter.ToSingle(totalGradeBytes, 0);
 
    byte[] percentBytes = reader.ReadBytes(4);
    double percent = BitConverter.ToSingle(percentBytes, 0);
 
    string[] names = name.Split(',');
    string lastName = names[0].Trim();
    string firstName = names[1].Trim();
 
    string line = String.Format("{0} {1} {2} {3}",
        firstName.PadRight(10), lastName.PadRight(10),
        totalGrade.ToString().PadRight(4),
        percent.ToString().PadRight(5));
 
    listBox1.Items.Add(line);
}

Open in new window

0
 
Pettitte96Author Commented:
I'm getting an error.

The code for reading the binary file is in a separate class from the main form, so it won't let me enter the listBox1.Items.Add(line)

Sorry to be so dense, but I'm VERY new at this.  I've attached a screenshot of what it's supposed to look like.  I've got everything else coded, I just can't figure out this binary file.
Project.doc
0
 
RyanAndresCommented:
You have all the information for parsing the binary file and using the data. The problem you're encountering is to execute code from another class in a form. All you need to do is instantiate your class containing the reader code inside of the form class.


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        
        Reader reader = new Reader();
        ArrayList list = reader.GetCourseGrades("out.txt");
 
        foreach (CourseGrade cg in list)
        {
            string line = String.Format("{0} {1} {2} {3}",
                cg.Fname.PadRight(10), cg.Lname.PadRight(10),
                cg.Totalgrade.ToString().PadRight(5),
                cg.Finalpercent.ToString().PadRight(5));
 
            listBox1.Items.Add(line);   
        }
    }
}
 
class Reader
{
    public ArrayList GetCourseGrades(string filename)
    {
        ArrayList courseGrades = new ArrayList();
        FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
        BinaryReader reader = new BinaryReader(stream);
 
        while (reader.PeekChar() != -1)
        {
            int nameLength = reader.ReadByte();
 
            byte[] nameBytes = reader.ReadBytes(nameLength);
            string name = Encoding.ASCII.GetString(nameBytes);
 
            byte[] totalGradeBytes = reader.ReadBytes(4);
            float totalGrade = BitConverter.ToSingle(totalGradeBytes, 0);
 
            byte[] percentBytes = reader.ReadBytes(4);
            float percent = BitConverter.ToSingle(percentBytes, 0);
 
            string[] names = name.Split(',');
            string lastName = names[0].Trim();
            string firstName = names[1].Trim();
 
            CourseGrade cg = new CourseGrade();
            cg.Fname = firstName;
            cg.Lname = lastName;
            cg.Totalgrade = totalGrade;
            cg.Finalpercent = percent;
 
            courseGrades.Add(cg);
        }
 
        return courseGrades;
    }
}

Open in new window

Q24376691.doc
0
 
Pettitte96Author Commented:
That gets me "Object Reference not set to an instance of an object" after I select the file.
    public partial class frmStudents : Form
    {
        private CourseGradesDB GradeDB;        
        private ArrayList lstArray;
 
        public frmStudents()
        {
            InitializeComponent();
            GradeDB = new CourseGradesDB();
        }
 
        private void btnLoadFileData_Click(object sender, EventArgs e)
        {
            try
            {
                ofdStudents.ShowDialog();
                CourseGradesData cgd = new CourseGradesData();
                lstArray = new ArrayList();
                lstArray = cgd.ReadBin(ofdStudents.FileName);
                cgd.sortLName(lstArray);
 
                foreach (CourseGradesData cg0 in lstArray)
                {
                    string line = String.Format("{0} {1} {2} {3}",
                        cg0.Fname.PadRight(10), cg0.Lname.PadRight(10),
                        cg0.Total.ToString().PadRight(5),
                        cg0.Percent.ToString().PadRight(5));
 
                    lstBinFile.Items.Add(line);
                }
 
            }
            catch (System.Exception exc)
            {
                lblError.Text = exc.Message;
            }
        }
    }
 
 
 
class CourseGradesData
    {
        private string szLname, szFname, szerror;
        private Int32 tpoints;
        private float finpercent;
 
        public CourseGradesData()
        {
        }
        
        public String Lname
        {
            get
            {
                return szLname;
            }
            set
            {
                szLname = value;
            }
        }
 
        public String Fname
        {
            get
            {
                return szFname;
            }
            set
            {
                szFname = value;
            }
        }
 
        public Int32 Total
        {
            get
            {
                return tpoints;
            }
            set
            {
                tpoints = value;
            }
        }
 
        public float Percent
        {
            get
            {
                return finpercent;
            }
            set
            {
                finpercent = value;
            }
        }
 
        public String Error
        {
            get
            {
                return szerror;
            }
            set
            {
                szerror = value;
            }
        }
 
        public float CalcPercent(Int32 tpoints)
        {
            finpercent = (tpoints / 400);
            return finpercent;
        }
		
        public ArrayList ReadBin(String filename)
        {            
            ArrayList cgList = new ArrayList();
            BinaryReader binfile = null;
            CourseGradesData cg1 = null;
            try
            {
                binfile = new BinaryReader(
                    new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Read));
 
                while (binfile.PeekChar() != -1)
                {                    
                    int nameLength = binfile.ReadByte();
 
                    byte[] nameBytes = binfile.ReadBytes(nameLength);
                    string name = Encoding.ASCII.GetString(nameBytes);
 
                    byte[] totalGradeBytes = binfile.ReadBytes(4);
                    float totalGrade = BitConverter.ToSingle(totalGradeBytes, 0);
 
                    byte[] percentBytes = binfile.ReadBytes(4);
                    float percent = BitConverter.ToSingle(percentBytes, 0);
 
                    string[] names = name.Split(',');
                    string lastName = names[0].Trim();
                    string firstName = names[1].Trim();
 
                    cg1.Fname = firstName;
                    cg1.Lname = lastName;
                    cg1.Total = Convert.ToInt32(totalGrade);
                    cg1.Percent = percent;
 
                    cgList.Add(cg1);
 
                }
                binfile.Close();
 
            }
            catch (System.IO.IOException exc)
            {
                Console.WriteLine(" Error in processing file"
                    + exc.Message);
            }                       
            return cgList;
        }// end of ReadBin        
    }

Open in new window

0
 
RyanAndresCommented:
CourseGradesData is the obejct which contain grade data.
I created another class called Reader which should contain the public ArrayList ReadBin(String filename) method.

Please see my code as I have 3 total classes.
0
 
Pettitte96Author Commented:
I am required to have the binary file read method in the CourseGradesData class.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.