Here is the problem:
Write a C# program that will read five scores, each on a separate line, from an external file named Unit09data.txt. Your program should then calculate the average of those scores and write the average, formatted to two decimal places in a different external file named output.txt. Be sure that your program handles IOExceptions.

The result should be 3.0 and create and write to another txt file outout.txt.

The exceptions seem to be working but it is not creating and writing to the output.txt file so I am not even sure if it is reading and computing this correctly.

Can anyone help?
Here is what I have..

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace Unit09Project
{
	
	public class frmExceptions : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Button btnOpen;
		private System.Windows.Forms.Label lblOutput;
		private StreamReader iFile; 
		private StreamWriter oFile;  
		private System.ComponentModel.Container components = null;

		public frmExceptions()
		{
			InitializeComponent();
		}

		/// Clean up any resources being used.
		
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.btnOpen = new System.Windows.Forms.Button();
			this.lblOutput = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// btnOpen
			// 
			this.btnOpen.Location = new System.Drawing.Point(100, 65);
			this.btnOpen.Name = "btnOpen";
			this.btnOpen.TabIndex = 0;
			this.btnOpen.Text = "Open File";
			this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
			// 
			// lblOutput
			// 
			this.lblOutput.Location = new System.Drawing.Point(20, 150);
			this.lblOutput.Name = "lblOutput";
			this.lblOutput.Size = new System.Drawing.Size(170, 23);
			this.lblOutput.TabIndex = 1;
			// 
			// frmExceptions
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(284, 244);
			this.Controls.Add(this.lblOutput);
			this.Controls.Add(this.btnOpen);
			this.Name = "frmExceptions";
			this.Text = "Unit 09 Project";
			this.Load += new System.EventHandler(this.frmExceptions_Load);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new frmExceptions());
		}

		private void frmExceptions_Load(object sender, System.EventArgs e)
		{
			
		}

		private void btnOpen_Click(object sender, System.EventArgs e)
		{
			
			int totalScore = 0;
			int scoreCount = 0;
			double averageTestScore;
			
			

			StreamReader iFile = new StreamReader(@"C:\Users\fjones\Documents\Visual Studio Projects\Unit09Project\bin\Debug\Unit09data.txt.txt");
			
			
			
			if(File.Exists(@"C:\Users\fjones\Documents\Visual Studio Projects\Unit09Project\bin\Debug\Unit09data.txt.txt"))
				try
				{
					totalScore += Convert.ToInt32(iFile.ReadLine());
					scoreCount++;
					averageTestScore = totalScore/scoreCount;
					StreamWriter oFile = new StreamWriter(@"C:\Users\fjones\Documents\Visual Studio Projects\bin\Debug\output.txt");
					oFile.Write(String.Format("The average of these scores is: {0}", averageTestScore));
				}
			
			catch (System.IO.IOException exc)
			{ 
				lblOutput.Text = exc.Message;
			}
			finally
			{
				iFile.Close();
			}

			lblOutput.Text = "Progress made";
		}

	}
}

Recommended Answers

All 18 Replies

Use loop to retrieve all five scores:

StreamReader sr = new StreamReader(@"input_file_path");
        int no = 0;
        int cnt = 0;
        while (sr.Peek() > 0)
        {
            no = no + Convert.ToInt32(sr.ReadLine());
            cnt++;
        }
        decimal avg = (decimal)no / cnt;
        StreamWriter wr = new StreamWriter(@"output_file_path");
        wr.Write("{0}", avg);
        wr.Flush();
        wr.Close();

It is still not creating and writing to an output.txt file.

if you have to create a file then you should not use:

StreamWriter oFile = new StreamWriter(@"C:\Users\fjones\Documents\Visual Studio Projects\bin\Debug\output.txt");

instead use this:

String file_name=@"c:\ab.txt";
using( FileStream fs = new FileStream(file_name, FileMode.OpenOrCreate, FileAccess.Write))
{
 //do something with open file
}

this will create a file if it doesn't exists and open it for writing.

DangerDev,
Use backslash character to form a path and OP wants to create a textstream not a byte stream.

commented: thanks to specify mistakes. :) +2

@ adatapost thanks for mentioning my mistakes. :)

regarding StreamWriter from msdn: "StreamWriter defaults to using an instance of UTF8Encoding unless specified otherwise."
so i think it would be ok to use it.
Please do post comments, if any.

would not this not work?

string avg = Convert.ToString(averageTestScore);
string aWrite="The average of these scores is: "+ avg;
System.IO.File.WriteAllLines(@"C:\Users\fjones\Documents\Visual Studio Projects\bin\Debug\output.txt", aWrite);

WriteAllLines will fail if the file already exists and is Read-Only:

The following conditions may cause an exception:
* The file exists and is read-only.
* The path name may be too long.
* The disk may be full.

You should be sure you put into a try-catch block at least.

The exceptions seem to be working but it is not creating and writing to the output.txt file so I am not even sure if it is reading and computing this correctly.

I like to toss message boxes in to check variables to be sure the correct output is coming during testing.

WriteAllLines will fail if the file already exists and is Read-Only

true and i agree with you but if he needs to create it it wouldn't already exist lol
But i definitely agree with the try-catch block to be on the safe side.

true and i agree with you but if he needs to create it it wouldn't already exist lol

Yea, I fired that one off a little quick and didn't notice the Read-Only attribute condition at first. I've never seen that static method before and I was afraid at first if the program was run more than once since there are no Open mode flags being passed in.

I like to toss message boxes in to check variables to be sure the correct output is coming during testing.

Not sure if you've seen this, but there is also an output window method you can use while in the debugger to output information, which you can go back and evaluate during execution and after exiting as well: System.Diagnostics.Debug.Write... methods.

Not sure if you've seen this, but there is also an output window method you can use while in the debugger to output information, which you can go back and evaluate during execution and after exiting as well: System.Diagnostics.Debug.Write... methods.

I will definitely look into it as i plan on doing some serious coding this weekend

Aha! One problem is solved. I have it where it is actually creating the output.txt file now.
Fixed it by changing the path to:

StreamWriter oFile = new StreamWriter("output.txt");

Now the problem is that the txt file is empty. It is not showing me my results.

This is what i have:

private void btnOpen_Click(object sender, System.EventArgs e)
		{
			
			StreamReader iFile = new StreamReader("Unit09data.txt.txt");

			int totalScore = 0;
			int scoreCount = 0;
			decimal averageTestScore;
			
			

			if(File.Exists("Unit09data.txt.txt"))
				try
				{
					while (iFile.Peek() > 0)
					{
						totalScore = totalScore + Convert.ToInt32(iFile.ReadLine());
						scoreCount++;
					}
					averageTestScore = totalScore/scoreCount;
					StreamWriter oFile = new StreamWriter("output.txt");
					oFile.Write(String.Format("The average of these scores is: {0}", averageTestScore));
					
				}
			
			catch (System.IO.IOException exc)
			{ 
				lblOutput.Text = exc.Message;
			}
			finally
			{
				iFile.Close();
			}

			lblOutput.Text = "Progress made";

QUESTIONS:
1) What does the input file data look like?
2) Is it throwing an IOException?

COMMENT: I would put iFile.Flush(); call prior to the iFile.Close(); in your "finally" block to ensure the memory buffer is flushed to the file.

Duh(me)!
Leave your iFile.Close(), but add oFile.Flush and oFile.Close()

This means you will have to either move the instantiation of the oFile object outside of the try block, or simply add the calls after your oFile.Write statement.

If you make those changes, I just ran a test and it was successful--good luck.

SUGGESTION: Remove the reference to the complete path and just use the filename. This way, you can move the exe and the input.txt file anywhere and it will run.

NEVERMIND: I see you already edited the code to do this.

Here are the changes I made for my test that worked:

public static void DoStreamReader()
        {
            StreamReader iFile = new StreamReader("Input.txt");

            int totalScore = 0;
            int scoreCount = 0;
            decimal averageTestScore;



            if (File.Exists("input.txt"))
                try
                {
                    while (iFile.Peek() > 0)
                    {
                        totalScore = totalScore + Convert.ToInt32(iFile.ReadLine());
                        scoreCount++;
                    }
                    averageTestScore = totalScore / scoreCount;
                    StreamWriter oFile = new StreamWriter("output.txt");
                    oFile.Write(String.Format("The average of these scores is: {0}", averageTestScore));
                    oFile.Flush(); // flush memory to your output file
                    oFile.Close(); // close your output file

                }

                catch (System.IO.IOException exc)
                {
                    //lblOutput.Text = exc.Message;
                }
                finally
                {
                    iFile.Close();
                }
        }

A better way that captures what I said in a finally block, but, ideally, you would also put both your Stream creations inside of a try block themselves or ensure the caller is doing so.

public static void DoStreamReader()
        {
            StreamReader iFile = new StreamReader("Input.txt");
            StreamWriter oFile = new StreamWriter("output.txt");

            int totalScore = 0;
            int scoreCount = 0;
            decimal averageTestScore;



            if (File.Exists("input.txt"))
                try
                {
                    while (iFile.Peek() > 0)
                    {
                        totalScore = totalScore + Convert.ToInt32(iFile.ReadLine());
                        scoreCount++;
                    }
                    averageTestScore = totalScore / scoreCount;
                    oFile.Write(String.Format("The average of these scores is: {0}", averageTestScore));

                }

                catch (System.IO.IOException exc)
                {
                    //lblOutput.Text = exc.Message;
                }
                finally
                {
                    iFile.Close();
                    oFile.Flush(); // flush memory to your output file
                    oFile.Close(); // close your output file
                }
        }

Duh(me)!
Leave your iFile.Close(), but add oFile.Flush and oFile.Close()

This means you will have to either move the instantiation of the oFile object outside of the try block, or simply add the calls after your oFile.Write statement.

That worked! Thank you!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.