Question:
How to read a text file into an array of objects in C#?
Nicole
2012-12-08 13:32:00 UTC
I have a text file of data that has employee information on it, formatted like so:
employee number
employee name
address
wage hours

I have an employee class set up like so:

class Employee
{
const double STATE_TAX = 0.075;
const double FEDERAL_TAX = 0.2;
const double OVERTIME = 1.5;
const int FULL_TIME = 40;
private int hours, otHours;
private double wage, pay, regPay, otPay;
int empNum;
string name, address;

public Employee()
{
empNum = 0;
name = "";
address = "";
wage = 0.00;
hours = 0;

}

public void SetEmpNum(int a)
{
empNum = a;
}

public void SetName(string a)
{
name = a;
}

public void SetAddress(string a)
{
address = a;
}
public void SetWage(double a)
{
wage = a;
}
public void SetHours(int a)
{
hours = a;
}
public int GetEmpNum()
{
return empNum;
}

public string GetName()
{
return name;
}


public string GetAddress()
{
return address;
}

public double GetWage()
{
return wage;
}

public int GetHours()
{
return hours;
}
//CalcSalary Method
//Purpose: to calculate the salary based on overtime and tax
//Paramters: none
//Returns: double pay
public double CalcSalary()
{
if (hours > FULL_TIME)
{
otHours = hours - FULL_TIME;
regPay = FULL_TIME * wage;
otPay = otHours * (wage * OVERTIME);
pay = regPay + otPay;
}
else pay = wage * hours;
return pay = pay - ((STATE_TAX * pay) + (FEDERAL_TAX * pay));
}
}
}

I need to figure out how to read the data from the file and put it into an array of Employee objects.
So far, it looks like this:
public partial class Form1 : Form
{
//initialize variables and constants
private StreamReader data;
string inputString;
string name = "";
int empNum = 0;
string address = "";
string[] payInfo = new string[2];
double wage = 0.00;
int hours = 0;
const int SIZE = 10;
Employee[] myEmployees = new Employee[SIZE];
int count = 0;
int numEmployees = 0;
//array of employees []


//open form
public Form1()
{
InitializeComponent();
}
//tool strip menu - open data file
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
Stream myStream = null;
OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "text files (*.txt)|*txt";

if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
data = new StreamReader(myStream);
//read data
inputString = data.ReadLine();
if (inputString != null)
{

empNum = int.Parse(inputString);
name = inputString;
address = inputString;
string[] payInfo = inputString.Split();
wage = double.Parse(payInfo[0]);
hours = int.Parse(payInfo[1]);

}

}
}
}

I know I'm missing a lot.. it's not fillng an array of employees or keeping track of the number of employees, which I need.
The end goal is to display the employee name, address, and net wage upon clicking the Next button. I think I have the event handlers set up OK, but I'm struggling with the data/class thing.
Help??
Four answers:
?
2012-12-08 14:18:47 UTC
You need a looping construct to read multiple employees, and make multiple calls to data.ReadLine() to get the next line.



data = new StreamReader(myStream);

//read data

inputString = data.ReadLine();

while (inputString != null)

{

    myEmployees[count] = new Employee();

    myEmployees[count].SetEmpNum( int.Parse(inputString) );

    myEmployees[count].SetName( data.ReadLine() );

    myEmployees[count].SetAddress( data.ReadLine() );

    string[] payInfo = data.ReadLine().Split();

    myEmployees[count].SetWage( double.Parse(payInfo[0]) );

    myEmployees[count].SetHours( int.Parse(payInfo[1]) );

    count++;

    inputString = data.ReadLine(); // id of next employee

}
peteams
2012-12-08 13:58:51 UTC
The correct way to read something from a file is to use serialization, that is a set of mechanisms that allow an object to be read or written to a stream in binary, XML, JSON or, as you would want, textual format. But that's a more advanced subject.



To do what you want I would change the lines that begin



if ((myStream = openFileDialog1.OpenFile()) != null)



to read something like:



var lines = File.ReadAllLines(openFileDialog1.FileName);

empNUm = int.Parse(lines[0]);

name = lines[1];

address = lines[2];



Also, as a side note, you have much code that uses member functions to access private data, e.g.



public void SetEmpNum(int a)

{

empNum = a;

}



public int GetEmpNum()

{

return empNum;

}



That's a piece of Java/C++ style that is cleaned up by properties in C++. You'd normally replace the above lines with either:



public int EmpNum { get { return empNum; } set { empNum = value; } }



or get rid of empNum all together and let the compiler do the work and write:



public int EmpNum { get; set; }
banegas
2016-10-14 02:30:20 UTC
you're on the right line in questioning so that you may use an array of shopper, in spite of the indisputable fact that the issue with utilising arrays is you may want to prefer to well known the way many aspects the array will contain once you declare it. in case you do not recognize what percentage strains will be on your document, you'll finally end up having to shop resizing the array each and every time you study a sparkling line from the document. it would want to be extra constructive to apply a listing, so that you may uncomplicated create a sparkling customer celebration for each new line on your document, and upload it to the record - lists do not care about minimum and optimal numbers of things they'll contain.
deonejuan
2012-12-08 13:52:19 UTC
C# is enough like java that maybe I can help you. I keep everything String until the last possible moment. I pass an array of String into the constructor of Employee

(java)

ArrayList emploees = new ArrayList<>();

Scanner sc = new Scann( fileInputStream);

while( sc.hasNext() ) {

String in = sc.nextLn();

String[] data = in.split(","); // can split using RegEx or specific char

employees.add( new Employee( data ) );

...

then, the Employee class would look like

public class Employee {

vars

// constructor

public Employee( String[] textData ) {

this.name = textData[0];

this.ID = Integer.parseInt( textData[ 1 ] );



hope that helps.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...