Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Reading from and writing to a txt file

PhillisPhillis Posts: 1Member
Hello everyone. I am new here and pretty new to programming in C#.
I am stuck on this program and I don't know how to get this to do what I want it to do.
I need to write a program that reads 5 scores from an external text file. When the user clicks on the button control it should calculate the average of those scores and then store the result of the calculation in a separate txt file(output.txt). Oh yeah and it needs to handle IOExceptions as well. All of the tutorials I've seen have either writing to or reading from, but never the two together and I am getting confused. Can someone help?
This is what I have so far:
[code]
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 inFile;
private StreamWriter fil;
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
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
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

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

private void frmExceptions_Load(object sender, System.EventArgs e)
{
string inValue;
if (File.Exists("Unit09data.txt"))
{
try
{
inFile = new StreamReader("Unit09data.txt");
}
catch (System.IO.IOException exc)
{
lblOutput.Text = exc.Message;
}
}
else
{
lblOutput.Text = "Progress made";
}
}

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

int totalScores = 0;
int scoreCount = 0;
double averageTestScore;

averageTestScore = totalScores / scoreCount;


}

}
}
[/code]
Am I headed in the right direction or totally off?

Comments

  • DataDinkDataDink Posts: 135Member
    To start let me answer your question (I'm going to so dome prodding down farther):
    you can get rid of the code in your "frmExceptions_Load" method. This method is called when your window is being created in memory - what you want is for stuff to happen when the user clicks on a button.


    in your "btnOpen_Click" ("btnOpen" is a good naming scheme btw) you will want to activate your code.

    I am going to assume that the file you are reading from just has one number per line - we can always adjust the code I give you here if this is not the case.

    You are correct to check that a file exists before attempting to work with it - so let's keep that, but instead of putting all of your code inside of an "If" block, let's just reverse the logic statement to say "if the file does NOT exist" and exit the method if this is the case. (it is always good to try to avoid as many nested block statements as possible)

    [code]
    private void btnOpen_Click(object sender, System.EventArgs e)
    {
    if (!File.Exists("Unit09data.txt"))
    return;

    [/code]
    (technically you would want to make "Unit09data.txt" a constant, but since this is an extreemly rare case where you actually know for a fact that you will never-ever-ever need to change this value then it is okay that it is hard-coded)

    Yes - using a try/catch block is the proper way to handle exceptions when working with files - because there are so many unknowns as to why a file operation might fail it is always good to attempt to handle the issue.
    However, if the file operation fails for some reason you don't want to continue with code - so you will also want a "return" statement in your "catch" block.

    [code]
    // this array will hold all of the scores from the file.
    string[] scores;

    try
    {
    // This is a built-in .net function that reads a text file
    // and returns each "line" from the file in an array of strings
    scores = File.ReadAllLines("Unit09data.txt");
    }
    catch (System.IO.IOException e)
    {
    lblOutput.Text = "There was an error reading the file: " + e.Message;
    return; // this will exit the method.
    }

    [/code]


    So another thing I'm assuming is that the file we are reading from is always going to be perfectly formatted - so I will not be checking for any kind of formatting errors - erroneous white-space or anything like that...

    From this point on our code can assume that we have successfuly read the file and now have an array of scores in the "scores" array. Otherwise the catch block would have fired and no further code in this method will be executed.

    Your set-up in your existing "btnOpen_Click" method show that you are correctly getting ready to add up a bunch of scores and divide them by the score count. In the code I am giving you, we already know the score count because it is the "length" of our array.

    [code]

    int totalScore = 0;
    int scoreCount = scores.Length;

    [/code]

    Now we need to go through each test score and add them up in the totalScores variable we just declared. Here I will do this using a "foreach" loop. Another thing to note is that "scores" is a string array and you can't add a string to an integer. Fortunately .NET provides functionality for converting strings into numbers. (again - I am assuming a perfect file - if there are any letters or extra spaces this will not work)

    [code]

    foreach (string score in scores)
    totalScore += int.Parse(score);

    [/code]

    Simple - yes?

    Now all we have to do is calculate the result and save it to another file. Saving is just as fragile as reading so we will want to handle exceptions here also. Since we are writing to a text file we will need to convert our result back into a string - which .NET also has built-in functionality for.

    [code]

    double averageTestScore = totalScore / scoreCount;

    try
    {
    // another couple of handy built-in functions:
    // WriteAllText creates a file and writes your text to it
    // .ToString() will return the string representation of any object
    File.WriteAllText(averageTestScore.ToString());
    }
    catch (System.IO.IOException e)
    {
    lblOutput.Text = "There was an error reading the file: " + e.Message;
    return;
    }

    [/code]

    Aaaand just for added spice, let's also display the result in lblOutput:

    [code]

    lblOutput.Text = "Your average score is: " + averageTestScore;
    }

    [/code]


    So here is that method all together:
    [code]
    private void btnOpen_Click(object sender, System.EventArgs e)
    {
    if (!File.Exists("Unit09data.txt"))
    return;

    string[] scores;

    try
    {
    scores = File.ReadAllLines("Unit09data.txt");
    }
    catch (System.IO.IOException e)
    {
    lblOutput.Text = "There was an error reading the file: " + e.Message;
    return;
    }

    int totalScore = 0;
    int scoreCount = scores.Length;

    foreach (string score in scores)
    totalScore += int.Parse(score);

    double averageTestScore = totalScore / scoreCount;

    try
    {
    File.WriteAllText(averageTestScore.ToString());
    }
    catch (System.IO.IOException e)
    {
    lblOutput.Text = "There was an error reading the file: " + e.Message;
    return;
    }

    lblOutput.Text = "Your average score is: " + averageTestScore;
    }
    [/code]

    I hope that helps solve your issue.


    Okay children, cover your eyes, I'm going to rant a little bit:

    You somehow have everything all in one file...

    The Control declarations, "Dispose" and "InitializeComponent" should be in a partial class file - did you purposely move these into the same file for some reason?

    If this is the case - just so you know there isn't any need to move them into the same file for the purpose of posting to a forum because for anyone answering questions, the code behind can be assumed and/or already known.

    This doesn't effect the operation of your program, it's just needlessly messy and makes longer posts to read/sort through - no big deal really.

    (- and I'll just say up-front if you don't care about coding and just want to pass a class then nevermind everything below, but if you would like to one day have a future in software then please read on...)

    However, on top of this you have your program entry point [italic]inside[/italic] of a windows form class. How did this get there? Visual Studio should have automatically generated a "Program" file and put this there. It should have even auto-generated the code inside the "Main" method that creates and displays your form. It even creates the form along with the partial class file that you don't even see unless you purposely seek it out. I am worried about this because your namespace is "Unit09Project" and this suggests you are taking a class or something.

    Now, I have no intention of belittling you or making you feel like you did anything wrong - you are a student and you are trying to pick up a very very good skill, [u][b]so good on you[/b][/u], no really - you are doing something that alot of people just don't have the capacity to do - but if someone is actually teaching you this crap they need to be fired (edit: using our nice words) - I'm not kidding, they are seriously hurting your chances at having a successful career in this by starting you off with some very, very bad habits. I'm only mentioning this because I am seeing a trend in the posts on this forum - it's almost like a lot of you are comming from the same class even.

    Even if you do not entirely understand all of the trillions of design methods there are out there and why to do what - when things start to click you will have a seriously hard time making the transition from learning to "knowing". You'll end up with code and practices that make no sense and when you start the learn the "whys" you will have to spend the majority of your time re-inventing the software design wheel in order to make what you know work.

    Yes, it's true that in teaching it is some times less confusing for the student to take out a lot of the structure in order to make learning fundamentals easier/possible - and yes I do this too. It is also true that I am not a teacher - I do not have a degree in teaching or psychology or anything that would make me an authority on proper training techniques.

    I am, however, very experienced at being a student of coding and can tell from personal experience that some of the habits I've seen on this forum that appear to be taught are going to be painful later on.

    Also I want to make a disclaimer that I am not promoting using patterns or practices for the sole purpose of using them. In fact many far smarter people have made many far more intelligent articles than I could ever make on how/why to not over-architect a solution. My own examples in this post have a serious lack of design - and this is due to the gravity of the project.

    That's not what I'm ranting about - what I am talking about is and the reason why I am taking the time to write this in a post is
    #1 this code was purposefully un-architected (is that a word?) - Microsoft put all of these default codes and structure in there for a reason. And no - what has been done here (in my oppinion) is making learning even harder.
    #2 this is not the first time I am seeing this identical (and apparently taught situation) - who is teaching this?
    #3 I want to break the mentality I see on a lot of forums of "I'm just showing you how to do something - not the right way to do it - you should come up with that yourself!" - shame on anyone that posts like this. It's just going to come back to haunt you in the future when you have to one day maintain that person's code. There is always a right way to do something - it's just not always easy to see.

    Anyways - sorry if anyone is offended by this post. I'm not trying to start a forum flame-war or anything, but please feel free to retort/defend yourself.
  • softwareskillsoftwareskill Posts: 4Member
    Here's a simple explanation on how to read data from and write data to text file in asp.net http://www.freedotnetapps.com/asp-net/how-to-read-data-from-and-write-data-to-text-file-in-asp-net/
  • softwareskillsoftwareskill Posts: 4Member
    Here's a simple explanation on how to read data from and write data to text file in asp.net http://www.freedotnetapps.com/asp-net/how-to-read-data-from-and-write-data-to-text-file-in-asp-net/
Sign In or Register to comment.